diff --git a/Cargo.lock b/Cargo.lock index 1b0c384..c1e4a40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,16 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + [[package]] name = "aes" version = "0.8.4" @@ -72,6 +82,24 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +[[package]] +name = "argon2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +dependencies = [ + "base64ct", + "blake2", + "cpufeatures", + "password-hash", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + [[package]] name = "arrayvec" version = "0.7.6" @@ -120,6 +148,19 @@ dependencies = [ "winnow", ] +[[package]] +name = "async-compat" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ba85bc55464dcbf728b56d97e119d673f4cf9062be330a9a26f3acf504a590" +dependencies = [ + "futures-core", + "futures-io", + "once_cell", + "pin-project-lite", + "tokio", +] + [[package]] name = "async-trait" version = "0.1.89" @@ -131,6 +172,15 @@ dependencies = [ "syn 2.0.109", ] +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -149,6 +199,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base32" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "022dfe9eb35f19ebbcb51e0b40a5ab759f46ad60cadf7297e0bd085afb50e076" + [[package]] name = "base58ck" version = "0.1.0" @@ -171,6 +227,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64ct" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a" + [[package]] name = "basic-toml" version = "0.1.10" @@ -316,12 +378,16 @@ name = "bitflags" version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +dependencies = [ + "serde_core", +] [[package]] name = "bitkitcore" -version = "0.1.31" +version = "0.1.32" dependencies = [ "async-trait", + "base64 0.22.1", "bip39", "bitcoin", "bitcoin-address-generator", @@ -332,6 +398,8 @@ dependencies = [ "lnurl-rs", "once_cell", "openssl", + "paykit-lib", + "pubky", "r2d2", "r2d2_sqlite", "rand 0.8.5", @@ -349,6 +417,7 @@ dependencies = [ "tokio", "uniffi", "url", + "urlencoding", "uuid", ] @@ -364,6 +433,28 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -528,7 +619,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -539,6 +630,7 @@ checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common", "inout", + "zeroize", ] [[package]] @@ -580,12 +672,66 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror", +] + [[package]] name = "const-oid" version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "cookie_store" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9" +dependencies = [ + "cookie", + "document-features", + "idna", + "log", + "publicsuffix", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + +[[package]] +name = "cordyceps" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688d7fbb8092b8de775ef2536f36c8c31f2bc4006ece2e8d8ad2d17d00ce0a2a" +dependencies = [ + "loom", + "tracing", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -621,6 +767,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crc32fast" version = "1.5.0" @@ -630,6 +791,27 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -649,9 +831,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core 0.6.4", "typenum", ] +[[package]] +name = "crypto_secretbox" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d6cf87adf719ddf43a805e92c6870a531aedda35ff640442cbaf8674e141e1" +dependencies = [ + "aead", + "cipher", + "generic-array", + "poly1305", + "salsa20", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.109", +] + [[package]] name = "der" version = "0.7.10" @@ -662,6 +887,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "deranged" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "diatomic-waker" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab03c107fafeb3ee9f5925686dbb7a73bc76e3932abb0d2b365cb64b169cf04c" + [[package]] name = "digest" version = "0.10.7" @@ -685,6 +925,30 @@ dependencies = [ "syn 2.0.109", ] +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "doxygen-rs" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "415b6ec780d34dcf624666747194393603d0373b7141eef01d12ee58881507d9" +dependencies = [ + "phf", +] + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + [[package]] name = "ecdsa" version = "0.16.9" @@ -698,6 +962,31 @@ dependencies = [ "signature", ] +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "serde", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", +] + [[package]] name = "elliptic-curve" version = "0.13.8" @@ -725,6 +1014,18 @@ dependencies = [ "serde", ] +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + [[package]] name = "equivalent" version = "1.0.2" @@ -769,6 +1070,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "find-msvc-tools" version = "0.1.4" @@ -785,6 +1092,17 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "spin 0.9.8", +] + [[package]] name = "fnv" version = "1.0.7" @@ -845,6 +1163,19 @@ dependencies = [ "futures-util", ] +[[package]] +name = "futures-buffered" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8e0e1f38ec07ba4abbde21eed377082f17ccb988be9d988a5adbf4bafc118fd" +dependencies = [ + "cordyceps", + "diatomic-waker", + "futures-core", + "pin-project-lite", + "spin 0.10.0", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -878,6 +1209,30 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.109", +] + [[package]] name = "futures-sink" version = "0.3.31" @@ -899,6 +1254,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-io", + "futures-macro", "futures-sink", "futures-task", "memchr", @@ -907,6 +1263,36 @@ dependencies = [ "slab", ] +[[package]] +name = "genawaiter" +version = "0.99.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c86bd0361bcbde39b13475e6e36cb24c329964aa2611be285289d1e4b751c1a0" +dependencies = [ + "futures-core", + "genawaiter-macro", +] + +[[package]] +name = "genawaiter-macro" +version = "0.99.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b32dfe1fdfc0bbde1f22a5da25355514b5e450c33a6af6770884c8750aedfbc" + +[[package]] +name = "generator" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" +dependencies = [ + "cc", + "cfg-if", + "libc", + "log", + "rustversion", + "windows", +] + [[package]] name = "generic-array" version = "0.14.9" @@ -973,6 +1359,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1006,12 +1401,60 @@ dependencies = [ "hashbrown 0.14.5", ] +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version", + "serde", + "spin 0.9.8", + "stable_deref_trait", +] + [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "heed" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd54745cfacb7b97dee45e8fdb91814b62bccddb481debb7de0f9ee6b7bf5b43" +dependencies = [ + "bitflags", + "byteorder", + "heed-traits", + "heed-types", + "libc", + "lmdb-master-sys", + "once_cell", + "page_size", + "synchronoise", + "url", +] + +[[package]] +name = "heed-traits" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3130048d404c57ce5a1ac61a903696e8fcde7e8c2991e9fcfc1f27c3ef74ff" + +[[package]] +name = "heed-types" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c255bdf46e07fb840d120a36dcc81f385140d7191c76a7391672675c01a55d" +dependencies = [ + "byteorder", + "heed-traits", +] + [[package]] name = "hex" version = "0.4.3" @@ -1088,6 +1531,12 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + [[package]] name = "hyper" version = "1.7.0" @@ -1179,7 +1628,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core", + "windows-core 0.62.2", ] [[package]] @@ -1380,6 +1829,12 @@ dependencies = [ "syn 2.0.109", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.177" @@ -1431,6 +1886,23 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[package]] +name = "lmdb-master-sys" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864808e0b19fb6dd3b70ba94ee671b82fce17554cf80aeb0a155c65bb08027df" +dependencies = [ + "cc", + "doxygen-rs", + "libc", +] + [[package]] name = "lnurl-rs" version = "0.9.0" @@ -1466,12 +1938,62 @@ version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lru" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465" + [[package]] name = "lru-slab" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +[[package]] +name = "mainline" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c258b001fa52b7270dc1a239b36a9b608b024e68733648c1757b025204fdc248" +dependencies = [ + "crc", + "document-features", + "dyn-clone", + "ed25519-dalek", + "flume", + "futures-lite", + "getrandom 0.2.16", + "lru", + "serde", + "serde_bencode", + "serde_bytes", + "sha1_smol", + "thiserror", + "tracing", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + [[package]] name = "memchr" version = "2.7.6" @@ -1532,6 +2054,36 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "ntimestamp" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c50f94c405726d3e0095e89e72f75ce7f6587b94a8bd8dc8054b73f65c0fd68c" +dependencies = [ + "base32", + "document-features", + "getrandom 0.2.16", + "httpdate", + "js-sys", + "once_cell", + "serde", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-traits" version = "0.2.19" @@ -1547,6 +2099,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "openssl" version = "0.10.74" @@ -1601,6 +2159,22 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "page_size" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" version = "0.12.5" @@ -1621,7 +2195,27 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-link", + "windows-link 0.2.1", +] + +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "paykit-lib" +version = "0.1.0" +source = "git+https://github.com/pubky/paykit-rs#7cfc0566402ee9a40ac83caed3b0ea055cbd2f8e" +dependencies = [ + "async-trait", + "pubky", ] [[package]] @@ -1640,6 +2234,48 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.109", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher 1.0.1", +] + [[package]] name = "pin-project-lite" version = "0.2.16" @@ -1652,6 +2288,54 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkarr" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb1f2f4311bae1da11f930c804c724c9914cf55ae51a9ee0440fc98826984f7" +dependencies = [ + "async-compat", + "base32", + "byteorder", + "bytes", + "cfg_aliases", + "document-features", + "dyn-clone", + "ed25519-dalek", + "futures-buffered", + "futures-lite", + "genawaiter", + "getrandom 0.2.16", + "heed", + "log", + "lru", + "mainline", + "ntimestamp", + "page_size", + "reqwest", + "rustls 0.23.35", + "rustls-webpki 0.102.8", + "self_cell", + "serde", + "sha1_smol", + "simple-dns", + "thiserror", + "tokio", + "tracing", + "url", + "wasm-bindgen-futures", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.32" @@ -1664,6 +2348,30 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "heapless", + "serde", +] + [[package]] name = "potential_utf" version = "0.1.4" @@ -1673,6 +2381,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -1700,6 +2414,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + [[package]] name = "ptr_meta" version = "0.1.4" @@ -1720,6 +2440,76 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "pubky" +version = "0.6.0-rc.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db16263a3ebeb88de3bfa26c264ac947f943967bc08c8032fe0bdd6f7b6d5db" +dependencies = [ + "base64 0.22.1", + "cookie", + "flume", + "futures-lite", + "futures-util", + "httpdate", + "log", + "pkarr", + "pubky-common", + "reqwest", + "thiserror", + "tokio", + "tracing", + "url", + "wasm-bindgen-futures", +] + +[[package]] +name = "pubky-common" +version = "0.6.0-rc.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "966b2d70da88a7a98e369276ae784e9187a0ddddc42d528e15aed12d24e6ccf5" +dependencies = [ + "argon2", + "base32", + "blake3", + "crypto_secretbox", + "ed25519-dalek", + "js-sys", + "once_cell", + "pkarr", + "postcard", + "pubky-timestamp", + "rand 0.9.2", + "serde", + "thiserror", + "url", +] + +[[package]] +name = "pubky-timestamp" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44aafc63c1eab1905e8a8378d2b085500540c9935b6d028908c8a50a5a246a3d" +dependencies = [ + "base32", + "document-features", + "getrandom 0.2.16", + "httpdate", + "js-sys", + "once_cell", + "serde", +] + +[[package]] +name = "publicsuffix" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf" +dependencies = [ + "idna", + "psl-types", +] + [[package]] name = "quinn" version = "0.11.9" @@ -1932,6 +2722,8 @@ checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" dependencies = [ "base64 0.22.1", "bytes", + "cookie", + "cookie_store", "futures-core", "http", "http-body", @@ -2079,6 +2871,15 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "1.1.2" @@ -2150,6 +2951,17 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustls-webpki" version = "0.103.8" @@ -2173,6 +2985,15 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] + [[package]] name = "scc" version = "2.4.0" @@ -2200,6 +3021,12 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -2347,6 +3174,12 @@ dependencies = [ "libc", ] +[[package]] +name = "self_cell" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16c2f82143577edb4921b71ede051dac62ca3c16084e918bf7b40c96ae10eb33" + [[package]] name = "semver" version = "1.0.27" @@ -2367,6 +3200,26 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde_bencode" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a70dfc7b7438b99896e7f8992363ab8e2c4ba26aa5ec675d32d1c3c2c33d413e" +dependencies = [ + "serde", + "serde_bytes", +] + +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -2437,6 +3290,12 @@ dependencies = [ "syn 2.0.109", ] +[[package]] +name = "sha1_smol" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" + [[package]] name = "sha2" version = "0.10.9" @@ -2448,6 +3307,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" @@ -2485,12 +3353,27 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" +[[package]] +name = "simple-dns" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee851d0e5e7af3721faea1843e8015e820a234f81fda3dea9247e15bac9a86a" +dependencies = [ + "bitflags", +] + [[package]] name = "siphasher" version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + [[package]] name = "slab" version = "0.4.11" @@ -2530,6 +3413,31 @@ dependencies = [ "winapi", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spin" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -2585,6 +3493,15 @@ dependencies = [ "futures-core", ] +[[package]] +name = "synchronoise" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dbc01390fc626ce8d1cffe3376ded2b72a11bb70e1c75f404a210e4daa4def2" +dependencies = [ + "crossbeam-queue", +] + [[package]] name = "synstructure" version = "0.13.2" @@ -2677,6 +3594,46 @@ dependencies = [ "syn 2.0.109", ] +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "time" +version = "0.3.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + +[[package]] +name = "time-macros" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinystr" version = "0.8.2" @@ -2841,9 +3798,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.109", +] + [[package]] name = "tracing-core" version = "0.1.34" @@ -2851,6 +3820,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -2971,7 +3970,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10f817868a3b171bb7bf259e882138d104deafde65684689b4694c846d322491" dependencies = [ "anyhow", - "siphasher", + "siphasher 0.3.11", "uniffi_internal_macros", "uniffi_pipeline", ] @@ -3001,6 +4000,16 @@ dependencies = [ "weedle2", ] +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "untrusted" version = "0.9.0" @@ -3038,6 +4047,12 @@ dependencies = [ "serde", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -3056,6 +4071,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "vcpkg" version = "0.2.15" @@ -3216,6 +4237,41 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.61.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +dependencies = [ + "windows-collections", + "windows-core 0.61.2", + "windows-future", + "windows-link 0.1.3", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core 0.61.2", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + [[package]] name = "windows-core" version = "0.62.2" @@ -3224,9 +4280,20 @@ checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", - "windows-link", - "windows-result", - "windows-strings", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", + "windows-threading", ] [[package]] @@ -3251,19 +4318,53 @@ dependencies = [ "syn 2.0.109", ] +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", +] + [[package]] name = "windows-result" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link", + "windows-link 0.2.1", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.3", ] [[package]] @@ -3272,7 +4373,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -3299,7 +4400,7 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -3324,7 +4425,7 @@ version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link", + "windows-link 0.2.1", "windows_aarch64_gnullvm 0.53.1", "windows_aarch64_msvc 0.53.1", "windows_i686_gnu 0.53.1", @@ -3335,6 +4436,15 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link 0.1.3", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" diff --git a/Cargo.toml b/Cargo.toml index 44d18b5..3a61668 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,12 @@ [package] name = "bitkitcore" -version = "0.1.31" +version = "0.1.32" edition = "2021" +[features] +default = ["pubky"] +pubky = ["dep:pubky", "paykit-lib/pubky"] + [lib] crate-type = ["cdylib", "staticlib", "rlib"] name = "bitkitcore" @@ -34,6 +38,10 @@ bitcoin-address-generator = "0.2.0" uuid = { version = "1.16.0", features = ["v4"] } hex = "0.4.3" bip39 = "2.0" +paykit-lib = { git = "https://github.com/pubky/paykit-rs", features = ["pubky"] } +pubky = { version = "0.6.0-rc.6", optional = true } +base64 = "0.22.1" +urlencoding = "2.1.3" [dev-dependencies] tokio = { version = "1.40.0", features = ["full"] } @@ -54,7 +62,6 @@ rustflags = [ "-C", "link-arg=-Wl,--allow-multiple-definition", ] - [[bin]] name = "example" path = "example/main.rs" diff --git a/Package.swift b/Package.swift index eb814ac..6d07f7b 100644 --- a/Package.swift +++ b/Package.swift @@ -3,8 +3,8 @@ import PackageDescription -let tag = "v0.1.31" -let checksum = "919d015a27448207dc26e54a07c846355ae7d78bfc970914940d7d5cc101811f" +let tag = "v0.1.32" +let checksum = "75e4d4c33d1c10bef7a65772eb5f0cb2485998470e1e69986861b647ccd0fa05" let url = "https://github.com/synonymdev/bitkit-core/releases/download/\(tag)/BitkitCore.xcframework.zip" let package = Package( diff --git a/README.md b/README.md index 5a9c2df..01d4d22 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,12 @@ - Derive addresses for specified paths - Retrieve account information - Handle responses from Trezor devices +- Paykit Module + - Integration with Pubky homeservers for payment endpoint management + - Import authenticated sessions from Pubky Ring via deeplinks + - Publish payment endpoints (Bitcoin addresses, Lightning invoices) + - Retrieve payment endpoints from other Pubky users + - Session lifecycle management and authentication ## Available Modules: Methods - Scanner @@ -436,6 +442,61 @@ common: Option, ) -> Result ``` +- Paykit: + - [create_pubky_ring_session_request](src/modules/paykit/README.md#api-reference): Generate a URL to request a session from Pubky Ring + ```rust + fn create_pubky_ring_session_request( + callback_url: String, + additional_params: Option> + ) -> Result + ``` + - [parse_paykit_deeplink](src/modules/paykit/README.md#api-reference): Parse a deeplink URL containing a session token + ```rust + fn parse_paykit_deeplink(url: String) -> Result + ``` + - [create_transport_from_session_token](src/modules/paykit/README.md#api-reference): Create an authenticated session from a token + ```rust + async fn create_transport_from_session_token( + token: SessionToken + ) -> Result + ``` + - [set_payment_endpoint](src/modules/paykit/README.md#api-reference): Store a payment endpoint on the user's homeserver + ```rust + async fn set_payment_endpoint( + client: &PubkyAuthenticatedTransport, + method: MethodId, + data: EndpointData + ) -> Result<(), PaykitError> + ``` + - [remove_payment_endpoint](src/modules/paykit/README.md#api-reference): Remove a payment endpoint from the user's homeserver + ```rust + async fn remove_payment_endpoint( + client: &PubkyAuthenticatedTransport, + method: MethodId + ) -> Result<(), PaykitError> + ``` + - [get_payment_list](src/modules/paykit/README.md#api-reference): Retrieve all payment methods for a given user + ```rust + async fn get_payment_list( + reader: &PubkyUnauthenticatedTransport, + payee: &PublicKey + ) -> Result + ``` + - [get_payment_endpoint](src/modules/paykit/README.md#api-reference): Retrieve a specific payment endpoint + ```rust + async fn get_payment_endpoint( + reader: &PubkyUnauthenticatedTransport, + payee: &PublicKey, + method: &MethodId + ) -> Result, PaykitError> + ``` + - [get_known_contacts](src/modules/paykit/README.md#api-reference): Get contacts list for a given user + ```rust + async fn get_known_contacts( + reader: &PubkyUnauthenticatedTransport, + key: &PublicKey + ) -> Result, PaykitError> + ``` ## Building the Bindings diff --git a/bindings/android/gradle.properties b/bindings/android/gradle.properties index 3cf2259..6e6611a 100644 --- a/bindings/android/gradle.properties +++ b/bindings/android/gradle.properties @@ -3,4 +3,4 @@ android.useAndroidX=true android.enableJetifier=true kotlin.code.style=official group=com.synonym -version=0.1.31 +version=0.1.32 diff --git a/bindings/android/lib/src/main/jniLibs/arm64-v8a/libbitkitcore.so b/bindings/android/lib/src/main/jniLibs/arm64-v8a/libbitkitcore.so index 467122e..6635c02 100755 Binary files a/bindings/android/lib/src/main/jniLibs/arm64-v8a/libbitkitcore.so and b/bindings/android/lib/src/main/jniLibs/arm64-v8a/libbitkitcore.so differ diff --git a/bindings/android/lib/src/main/jniLibs/armeabi-v7a/libbitkitcore.so b/bindings/android/lib/src/main/jniLibs/armeabi-v7a/libbitkitcore.so index 0871748..0335d06 100755 Binary files a/bindings/android/lib/src/main/jniLibs/armeabi-v7a/libbitkitcore.so and b/bindings/android/lib/src/main/jniLibs/armeabi-v7a/libbitkitcore.so differ diff --git a/bindings/android/lib/src/main/jniLibs/x86/libbitkitcore.so b/bindings/android/lib/src/main/jniLibs/x86/libbitkitcore.so index ec15abd..69308af 100755 Binary files a/bindings/android/lib/src/main/jniLibs/x86/libbitkitcore.so and b/bindings/android/lib/src/main/jniLibs/x86/libbitkitcore.so differ diff --git a/bindings/android/lib/src/main/jniLibs/x86_64/libbitkitcore.so b/bindings/android/lib/src/main/jniLibs/x86_64/libbitkitcore.so index 57ae407..54d90f9 100755 Binary files a/bindings/android/lib/src/main/jniLibs/x86_64/libbitkitcore.so and b/bindings/android/lib/src/main/jniLibs/x86_64/libbitkitcore.so differ diff --git a/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.android.kt b/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.android.kt index 4e5d0ab..0cbdae3 100644 --- a/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.android.kt +++ b/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.android.kt @@ -19,6 +19,8 @@ package com.synonym.bitkitcore import com.sun.jna.Library import com.sun.jna.Native import com.sun.jna.Structure +import android.os.Build +import androidx.annotation.RequiresApi import kotlin.coroutines.resume import kotlinx.coroutines.CancellableContinuation import kotlinx.coroutines.DelicateCoroutinesApi @@ -1115,6 +1117,48 @@ internal interface UniffiForeignFutureCompleteVoid: com.sun.jna.Callback { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1205,9 +1249,18 @@ internal object IntegrityCheckingUniffiLib : Library { if (uniffi_bitkitcore_checksum_func_create_cjit_entry() != 51504.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (uniffi_bitkitcore_checksum_func_create_deeplink_from_token() != 51091.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (uniffi_bitkitcore_checksum_func_create_order() != 33461.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (uniffi_bitkitcore_checksum_func_create_pubky_ring_session_request() != 2842.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (uniffi_bitkitcore_checksum_func_create_session_token_from_keypair() != 61582.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (uniffi_bitkitcore_checksum_func_create_withdraw_callback_url() != 39350.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } @@ -1229,6 +1282,9 @@ internal object IntegrityCheckingUniffiLib : Library { if (uniffi_bitkitcore_checksum_func_derive_private_key() != 25155.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (uniffi_bitkitcore_checksum_func_deserialize_token_to_session() != 9427.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (uniffi_bitkitcore_checksum_func_entropy_to_mnemonic() != 26123.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } @@ -1286,6 +1342,9 @@ internal object IntegrityCheckingUniffiLib : Library { if (uniffi_bitkitcore_checksum_func_get_info() != 43607.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (uniffi_bitkitcore_checksum_func_get_known_contacts() != 14867.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (uniffi_bitkitcore_checksum_func_get_lnurl_invoice() != 5475.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } @@ -1298,6 +1357,12 @@ internal object IntegrityCheckingUniffiLib : Library { if (uniffi_bitkitcore_checksum_func_get_payment() != 29170.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (uniffi_bitkitcore_checksum_func_get_payment_endpoint() != 60834.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (uniffi_bitkitcore_checksum_func_get_payment_list() != 49866.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (uniffi_bitkitcore_checksum_func_get_pre_activity_metadata() != 53126.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } @@ -1334,6 +1399,9 @@ internal object IntegrityCheckingUniffiLib : Library { if (uniffi_bitkitcore_checksum_func_open_channel() != 21402.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (uniffi_bitkitcore_checksum_func_parse_paykit_deeplink() != 40846.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (uniffi_bitkitcore_checksum_func_refresh_active_cjit_entries() != 5324.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } @@ -1361,6 +1429,9 @@ internal object IntegrityCheckingUniffiLib : Library { if (uniffi_bitkitcore_checksum_func_remove_closed_channel_by_id() != 17150.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (uniffi_bitkitcore_checksum_func_remove_payment_endpoint() != 692.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (uniffi_bitkitcore_checksum_func_remove_pre_activity_metadata_tags() != 1991.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } @@ -1370,6 +1441,12 @@ internal object IntegrityCheckingUniffiLib : Library { if (uniffi_bitkitcore_checksum_func_reset_pre_activity_metadata_tags() != 34703.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (uniffi_bitkitcore_checksum_func_serialize_session_to_token() != 52557.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (uniffi_bitkitcore_checksum_func_set_payment_endpoint() != 19775.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (uniffi_bitkitcore_checksum_func_test_notification() != 32857.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } @@ -1442,12 +1519,36 @@ internal object IntegrityCheckingUniffiLib : Library { if (uniffi_bitkitcore_checksum_func_validate_mnemonic() != 31005.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (uniffi_bitkitcore_checksum_func_validate_paykit_deeplink() != 64617.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (uniffi_bitkitcore_checksum_func_wipe_all_closed_channels() != 41511.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } if (uniffi_bitkitcore_checksum_func_wipe_all_databases() != 54605.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_remove_payment_endpoint() != 6181.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_set_payment_endpoint() != 9801.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_known_contacts() != 59528.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_endpoint() != 53072.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_list() != 50101.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (uniffi_bitkitcore_checksum_constructor_pubkyauthenticatedtransport_new() != 38771.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (uniffi_bitkitcore_checksum_constructor_pubkyunauthenticatedtransport_new() != 43061.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } } // Integrity check functions only @@ -1482,9 +1583,18 @@ internal object IntegrityCheckingUniffiLib : Library { external fun uniffi_bitkitcore_checksum_func_create_cjit_entry( ): Short @JvmStatic + external fun uniffi_bitkitcore_checksum_func_create_deeplink_from_token( + ): Short + @JvmStatic external fun uniffi_bitkitcore_checksum_func_create_order( ): Short @JvmStatic + external fun uniffi_bitkitcore_checksum_func_create_pubky_ring_session_request( + ): Short + @JvmStatic + external fun uniffi_bitkitcore_checksum_func_create_session_token_from_keypair( + ): Short + @JvmStatic external fun uniffi_bitkitcore_checksum_func_create_withdraw_callback_url( ): Short @JvmStatic @@ -1506,6 +1616,9 @@ internal object IntegrityCheckingUniffiLib : Library { external fun uniffi_bitkitcore_checksum_func_derive_private_key( ): Short @JvmStatic + external fun uniffi_bitkitcore_checksum_func_deserialize_token_to_session( + ): Short + @JvmStatic external fun uniffi_bitkitcore_checksum_func_entropy_to_mnemonic( ): Short @JvmStatic @@ -1563,6 +1676,9 @@ internal object IntegrityCheckingUniffiLib : Library { external fun uniffi_bitkitcore_checksum_func_get_info( ): Short @JvmStatic + external fun uniffi_bitkitcore_checksum_func_get_known_contacts( + ): Short + @JvmStatic external fun uniffi_bitkitcore_checksum_func_get_lnurl_invoice( ): Short @JvmStatic @@ -1575,6 +1691,12 @@ internal object IntegrityCheckingUniffiLib : Library { external fun uniffi_bitkitcore_checksum_func_get_payment( ): Short @JvmStatic + external fun uniffi_bitkitcore_checksum_func_get_payment_endpoint( + ): Short + @JvmStatic + external fun uniffi_bitkitcore_checksum_func_get_payment_list( + ): Short + @JvmStatic external fun uniffi_bitkitcore_checksum_func_get_pre_activity_metadata( ): Short @JvmStatic @@ -1611,6 +1733,9 @@ internal object IntegrityCheckingUniffiLib : Library { external fun uniffi_bitkitcore_checksum_func_open_channel( ): Short @JvmStatic + external fun uniffi_bitkitcore_checksum_func_parse_paykit_deeplink( + ): Short + @JvmStatic external fun uniffi_bitkitcore_checksum_func_refresh_active_cjit_entries( ): Short @JvmStatic @@ -1638,6 +1763,9 @@ internal object IntegrityCheckingUniffiLib : Library { external fun uniffi_bitkitcore_checksum_func_remove_closed_channel_by_id( ): Short @JvmStatic + external fun uniffi_bitkitcore_checksum_func_remove_payment_endpoint( + ): Short + @JvmStatic external fun uniffi_bitkitcore_checksum_func_remove_pre_activity_metadata_tags( ): Short @JvmStatic @@ -1647,6 +1775,12 @@ internal object IntegrityCheckingUniffiLib : Library { external fun uniffi_bitkitcore_checksum_func_reset_pre_activity_metadata_tags( ): Short @JvmStatic + external fun uniffi_bitkitcore_checksum_func_serialize_session_to_token( + ): Short + @JvmStatic + external fun uniffi_bitkitcore_checksum_func_set_payment_endpoint( + ): Short + @JvmStatic external fun uniffi_bitkitcore_checksum_func_test_notification( ): Short @JvmStatic @@ -1719,12 +1853,36 @@ internal object IntegrityCheckingUniffiLib : Library { external fun uniffi_bitkitcore_checksum_func_validate_mnemonic( ): Short @JvmStatic + external fun uniffi_bitkitcore_checksum_func_validate_paykit_deeplink( + ): Short + @JvmStatic external fun uniffi_bitkitcore_checksum_func_wipe_all_closed_channels( ): Short @JvmStatic external fun uniffi_bitkitcore_checksum_func_wipe_all_databases( ): Short @JvmStatic + external fun uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_remove_payment_endpoint( + ): Short + @JvmStatic + external fun uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_set_payment_endpoint( + ): Short + @JvmStatic + external fun uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_known_contacts( + ): Short + @JvmStatic + external fun uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_endpoint( + ): Short + @JvmStatic + external fun uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_list( + ): Short + @JvmStatic + external fun uniffi_bitkitcore_checksum_constructor_pubkyauthenticatedtransport_new( + ): Short + @JvmStatic + external fun uniffi_bitkitcore_checksum_constructor_pubkyunauthenticatedtransport_new( + ): Short + @JvmStatic external fun ffi_bitkitcore_uniffi_contract_version( ): Int } @@ -1739,6 +1897,65 @@ internal object UniffiLib : Library { // No need to check the contract version and checksums, since // we already did that with `IntegrityCheckingUniffiLib` above. } + // The Cleaner for the whole library + internal val CLEANER: UniffiCleaner by lazy { + UniffiCleaner.create() + } + @JvmStatic + external fun uniffi_bitkitcore_fn_clone_pubkyauthenticatedtransport( + `ptr`: Pointer?, + uniffiCallStatus: UniffiRustCallStatus, + ): Pointer? + @JvmStatic + external fun uniffi_bitkitcore_fn_free_pubkyauthenticatedtransport( + `ptr`: Pointer?, + uniffiCallStatus: UniffiRustCallStatus, + ): Unit + @JvmStatic + external fun uniffi_bitkitcore_fn_constructor_pubkyauthenticatedtransport_new( + uniffiCallStatus: UniffiRustCallStatus, + ): Pointer? + @JvmStatic + external fun uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_remove_payment_endpoint( + `ptr`: Pointer?, + `method`: RustBufferByValue, + ): Long + @JvmStatic + external fun uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_set_payment_endpoint( + `ptr`: Pointer?, + `method`: RustBufferByValue, + `data`: RustBufferByValue, + ): Long + @JvmStatic + external fun uniffi_bitkitcore_fn_clone_pubkyunauthenticatedtransport( + `ptr`: Pointer?, + uniffiCallStatus: UniffiRustCallStatus, + ): Pointer? + @JvmStatic + external fun uniffi_bitkitcore_fn_free_pubkyunauthenticatedtransport( + `ptr`: Pointer?, + uniffiCallStatus: UniffiRustCallStatus, + ): Unit + @JvmStatic + external fun uniffi_bitkitcore_fn_constructor_pubkyunauthenticatedtransport_new( + uniffiCallStatus: UniffiRustCallStatus, + ): Pointer? + @JvmStatic + external fun uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_known_contacts( + `ptr`: Pointer?, + `key`: RustBufferByValue, + ): Long + @JvmStatic + external fun uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_endpoint( + `ptr`: Pointer?, + `payee`: RustBufferByValue, + `method`: RustBufferByValue, + ): Long + @JvmStatic + external fun uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_list( + `ptr`: Pointer?, + `payee`: RustBufferByValue, + ): Long @JvmStatic external fun uniffi_bitkitcore_fn_func_activity_wipe_all( uniffiCallStatus: UniffiRustCallStatus, @@ -1793,12 +2010,34 @@ internal object UniffiLib : Library { `options`: RustBufferByValue, ): Long @JvmStatic + external fun uniffi_bitkitcore_fn_func_create_deeplink_from_token( + `baseUrl`: RustBufferByValue, + `action`: RustBufferByValue, + `token`: RustBufferByValue, + `additionalParams`: RustBufferByValue, + uniffiCallStatus: UniffiRustCallStatus, + ): RustBufferByValue + @JvmStatic external fun uniffi_bitkitcore_fn_func_create_order( `lspBalanceSat`: Long, `channelExpiryWeeks`: Int, `options`: RustBufferByValue, ): Long @JvmStatic + external fun uniffi_bitkitcore_fn_func_create_pubky_ring_session_request( + `callbackUrl`: RustBufferByValue, + `additionalParams`: RustBufferByValue, + uniffiCallStatus: UniffiRustCallStatus, + ): RustBufferByValue + @JvmStatic + external fun uniffi_bitkitcore_fn_func_create_session_token_from_keypair( + `publicKey`: RustBufferByValue, + `secretKey`: RustBufferByValue, + `homeserverUrl`: RustBufferByValue, + `expiresInSeconds`: RustBufferByValue, + uniffiCallStatus: UniffiRustCallStatus, + ): RustBufferByValue + @JvmStatic external fun uniffi_bitkitcore_fn_func_create_withdraw_callback_url( `k1`: RustBufferByValue, `callback`: RustBufferByValue, @@ -1847,6 +2086,11 @@ internal object UniffiLib : Library { uniffiCallStatus: UniffiRustCallStatus, ): RustBufferByValue @JvmStatic + external fun uniffi_bitkitcore_fn_func_deserialize_token_to_session( + `token`: RustBufferByValue, + uniffiCallStatus: UniffiRustCallStatus, + ): RustBufferByValue + @JvmStatic external fun uniffi_bitkitcore_fn_func_entropy_to_mnemonic( `entropy`: RustBufferByValue, uniffiCallStatus: UniffiRustCallStatus, @@ -1949,6 +2193,11 @@ internal object UniffiLib : Library { `refresh`: RustBufferByValue, ): Long @JvmStatic + external fun uniffi_bitkitcore_fn_func_get_known_contacts( + `reader`: Pointer?, + `key`: RustBufferByValue, + ): Long + @JvmStatic external fun uniffi_bitkitcore_fn_func_get_lnurl_invoice( `address`: RustBufferByValue, `amountSatoshis`: Long, @@ -1968,6 +2217,17 @@ internal object UniffiLib : Library { `paymentId`: RustBufferByValue, ): Long @JvmStatic + external fun uniffi_bitkitcore_fn_func_get_payment_endpoint( + `reader`: Pointer?, + `payee`: RustBufferByValue, + `method`: RustBufferByValue, + ): Long + @JvmStatic + external fun uniffi_bitkitcore_fn_func_get_payment_list( + `reader`: Pointer?, + `payee`: RustBufferByValue, + ): Long + @JvmStatic external fun uniffi_bitkitcore_fn_func_get_pre_activity_metadata( `searchKey`: RustBufferByValue, `searchByAddress`: Byte, @@ -2033,6 +2293,11 @@ internal object UniffiLib : Library { `connectionString`: RustBufferByValue, ): Long @JvmStatic + external fun uniffi_bitkitcore_fn_func_parse_paykit_deeplink( + `url`: RustBufferByValue, + uniffiCallStatus: UniffiRustCallStatus, + ): RustBufferByValue + @JvmStatic external fun uniffi_bitkitcore_fn_func_refresh_active_cjit_entries( ): Long @JvmStatic @@ -2079,6 +2344,11 @@ internal object UniffiLib : Library { uniffiCallStatus: UniffiRustCallStatus, ): Byte @JvmStatic + external fun uniffi_bitkitcore_fn_func_remove_payment_endpoint( + `client`: Pointer?, + `method`: RustBufferByValue, + ): Long + @JvmStatic external fun uniffi_bitkitcore_fn_func_remove_pre_activity_metadata_tags( `paymentId`: RustBufferByValue, `tags`: RustBufferByValue, @@ -2096,6 +2366,17 @@ internal object UniffiLib : Library { uniffiCallStatus: UniffiRustCallStatus, ): Unit @JvmStatic + external fun uniffi_bitkitcore_fn_func_serialize_session_to_token( + `sessionData`: RustBufferByValue, + uniffiCallStatus: UniffiRustCallStatus, + ): RustBufferByValue + @JvmStatic + external fun uniffi_bitkitcore_fn_func_set_payment_endpoint( + `client`: Pointer?, + `method`: RustBufferByValue, + `data`: RustBufferByValue, + ): Long + @JvmStatic external fun uniffi_bitkitcore_fn_func_test_notification( `deviceToken`: RustBufferByValue, `secretMessage`: RustBufferByValue, @@ -2293,6 +2574,11 @@ internal object UniffiLib : Library { uniffiCallStatus: UniffiRustCallStatus, ): Unit @JvmStatic + external fun uniffi_bitkitcore_fn_func_validate_paykit_deeplink( + `url`: RustBufferByValue, + uniffiCallStatus: UniffiRustCallStatus, + ): Byte + @JvmStatic external fun uniffi_bitkitcore_fn_func_wipe_all_closed_channels( uniffiCallStatus: UniffiRustCallStatus, ): Unit @@ -2575,6 +2861,69 @@ public fun uniffiEnsureInitialized() { // Public interface members begin here. +// The cleaner interface for Object finalization code to run. +// This is the entry point to any implementation that we're using. +// +// The cleaner registers disposables and returns cleanables, so now we are +// defining a `UniffiCleaner` with a `UniffiClenaer.Cleanable` to abstract the +// different implementations available at compile time. +public interface UniffiCleaner { + public interface Cleanable { + public fun clean() + } + + public fun register(resource: Any, disposable: Disposable): UniffiCleaner.Cleanable + + public companion object +} +// The fallback Jna cleaner, which is available for both Android, and the JVM. +private class UniffiJnaCleaner : UniffiCleaner { + private val cleaner = com.sun.jna.internal.Cleaner.getCleaner() + + override fun register(resource: Any, disposable: Disposable): UniffiCleaner.Cleanable = + UniffiJnaCleanable(cleaner.register(resource, UniffiCleanerAction(disposable))) +} + +private class UniffiJnaCleanable( + private val cleanable: com.sun.jna.internal.Cleaner.Cleanable, +) : UniffiCleaner.Cleanable { + override fun clean() = cleanable.clean() +} + +private class UniffiCleanerAction(private val disposable: Disposable): Runnable { + override fun run() { + disposable.destroy() + } +} + +// The SystemCleaner, available from API Level 33. +// Some API Level 33 OSes do not support using it, so we require API Level 34. +@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) +private class AndroidSystemCleaner : UniffiCleaner { + private val cleaner = android.system.SystemCleaner.cleaner() + + override fun register(resource: Any, disposable: Disposable): UniffiCleaner.Cleanable = + AndroidSystemCleanable(cleaner.register(resource, UniffiCleanerAction(disposable))) +} + +@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) +private class AndroidSystemCleanable( + private val cleanable: java.lang.ref.Cleaner.Cleanable, +) : UniffiCleaner.Cleanable { + override fun clean() = cleanable.clean() +} + +private fun UniffiCleaner.Companion.create(): UniffiCleaner { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + try { + return AndroidSystemCleaner() + } catch (_: IllegalAccessError) { + // (For Compose preview) Fallback to UniffiJnaCleaner if AndroidSystemCleaner is + // unavailable, even for API level 34 or higher. + } + } + return UniffiJnaCleaner() +} public object FfiConverterUByte: FfiConverter { @@ -2640,6 +2989,27 @@ public object FfiConverterULong: FfiConverter { } +public object FfiConverterLong: FfiConverter { + override fun lift(value: Long): Long { + return value + } + + override fun read(buf: ByteBuffer): Long { + return buf.getLong() + } + + override fun lower(value: Long): Long { + return value + } + + override fun allocationSize(value: Long): ULong = 8UL + + override fun write(value: Long, buf: ByteBuffer) { + buf.putLong(value) + } +} + + public object FfiConverterDouble: FfiConverter { override fun lift(value: Double): Double { return value @@ -2653,96 +3023,544 @@ public object FfiConverterDouble: FfiConverter { return value } - override fun allocationSize(value: Double): ULong = 8UL - - override fun write(value: Double, buf: ByteBuffer) { - buf.putDouble(value) + override fun allocationSize(value: Double): ULong = 8UL + + override fun write(value: Double, buf: ByteBuffer) { + buf.putDouble(value) + } +} + + +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): ULong = 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: RustBufferByValue): String { + try { + require(value.len <= Int.MAX_VALUE) { + val length = value.len + "cannot handle RustBuffer longer than Int.MAX_VALUE bytes: length is $length" + } + val byteArr = value.asByteBuffer()!!.get(value.len.toInt()) + return byteArr.decodeToString() + } finally { + RustBufferHelper.free(value) + } + } + + override fun read(buf: ByteBuffer): String { + val len = buf.getInt() + val byteArr = buf.get(len) + return byteArr.decodeToString() + } + + override fun lower(value: String): RustBufferByValue { + // TODO: prevent allocating a new byte array here + val encoded = value.encodeToByteArray(throwOnInvalidSequence = true) + return RustBufferHelper.allocValue(encoded.size.toULong()).apply { + asByteBuffer()!!.put(encoded) + } + } + + // 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) { + // TODO: prevent allocating a new byte array here + val encoded = value.encodeToByteArray(throwOnInvalidSequence = true) + buf.putInt(encoded.size) + buf.put(encoded) + } +} + + +public object FfiConverterByteArray: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): ByteArray { + val len = buf.getInt() + val byteArr = buf.get(len) + 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) + } +} + + + +/** + * Authenticated transport wrapper for Paykit write operations. + */ +public open class PubkyAuthenticatedTransport: Disposable, PubkyAuthenticatedTransportInterface { + + public constructor(pointer: Pointer) { + this.pointer = pointer + this.cleanable = UniffiLib.CLEANER.register(this, UniffiPointerDestroyer(pointer)) + } + + /** + * This constructor can be used to instantiate a fake object. Only used for tests. Any + * attempt to actually use an object constructed this way will fail as there is no + * connected Rust object. + */ + public constructor(noPointer: NoPointer) { + this.pointer = null + this.cleanable = UniffiLib.CLEANER.register(this, UniffiPointerDestroyer(null)) + } + /** + * Creates a new authenticated transport. + * Note: This requires proper session initialization which should be handled + * by the application layer. For now, this returns an error indicating the + * need for external session management. + */ + public constructor() : this( + uniffiRustCallWithError(PaykitExceptionErrorHandler) { uniffiRustCallStatus -> + UniffiLib.uniffi_bitkitcore_fn_constructor_pubkyauthenticatedtransport_new( + uniffiRustCallStatus, + ) + }!! + ) + + protected val pointer: Pointer? + protected val cleanable: UniffiCleaner.Cleanable + + private val wasDestroyed: kotlinx.atomicfu.AtomicBoolean = kotlinx.atomicfu.atomic(false) + private val callCounter: kotlinx.atomicfu.AtomicLong = kotlinx.atomicfu.atomic(1L) + + private val lock = kotlinx.atomicfu.locks.ReentrantLock() + + private fun synchronized(block: () -> T): T { + lock.lock() + try { + return block() + } finally { + lock.unlock() + } + } + + override fun destroy() { + // Only allow a single call to this method. + // TODO: maybe we should log a warning if called more than once? + if (this.wasDestroyed.compareAndSet(false, true)) { + // This decrement always matches the initial count of 1 given at creation time. + if (this.callCounter.decrementAndGet() == 0L) { + cleanable.clean() + } + } + } + + override fun close() { + synchronized { this.destroy() } + } + + internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { + // Check and increment the call counter, to keep the object alive. + // This needs a compare-and-set retry loop in case of concurrent updates. + do { + val c = this.callCounter.value + if (c == 0L) { + throw IllegalStateException("${this::class::simpleName} object has already been destroyed") + } + if (c == Long.MAX_VALUE) { + throw IllegalStateException("${this::class::simpleName} call counter would overflow") + } + } while (! this.callCounter.compareAndSet(c, c + 1L)) + // Now we can safely do the method call without the pointer being freed concurrently. + try { + return block(this.uniffiClonePointer()) + } finally { + // This decrement always matches the increment we performed above. + if (this.callCounter.decrementAndGet() == 0L) { + cleanable.clean() + } + } + } + + // Use a static inner class instead of a closure so as not to accidentally + // capture `this` as part of the cleanable's action. + private class UniffiPointerDestroyer(private val pointer: Pointer?) : Disposable { + override fun destroy() { + pointer?.let { ptr -> + uniffiRustCall { status -> + UniffiLib.uniffi_bitkitcore_fn_free_pubkyauthenticatedtransport(ptr, status) + } + } + } + } + + public fun uniffiClonePointer(): Pointer { + return uniffiRustCall { status -> + UniffiLib.uniffi_bitkitcore_fn_clone_pubkyauthenticatedtransport(pointer!!, status) + }!! + } + + + /** + * Removes a payment endpoint. + * + * # Parameters + * - `method`: Payment method identifier to remove + * + * # Returns + * - `Ok(())` on successful removal + * - `Err` if the endpoint doesn't exist or transport fails + */ + @Throws(PaykitException::class, kotlin.coroutines.cancellation.CancellationException::class) + public override suspend fun `removePaymentEndpoint`(`method`: MethodId) { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_remove_payment_endpoint( + thisPtr, + FfiConverterTypeMethodId.lower(`method`), + ) + }, + { future, callback, continuation -> UniffiLib.ffi_bitkitcore_rust_future_poll_void(future, callback, continuation) }, + { future, continuation -> UniffiLib.ffi_bitkitcore_rust_future_complete_void(future, continuation) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_free_void(future) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_cancel_void(future) }, + // lift function + { Unit }, + + // Error FFI converter + PaykitExceptionErrorHandler, + ) + } + + /** + * Stores or updates a payment endpoint. + * + * # Parameters + * - `method`: Payment method identifier (e.g., "lightning", "onchain") + * - `data`: Endpoint data payload (UTF-8 JSON or other text format) + */ + @Throws(PaykitException::class, kotlin.coroutines.cancellation.CancellationException::class) + public override suspend fun `setPaymentEndpoint`(`method`: MethodId, `data`: EndpointData) { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_set_payment_endpoint( + thisPtr, + FfiConverterTypeMethodId.lower(`method`), + FfiConverterTypeEndpointData.lower(`data`), + ) + }, + { future, callback, continuation -> UniffiLib.ffi_bitkitcore_rust_future_poll_void(future, callback, continuation) }, + { future, continuation -> UniffiLib.ffi_bitkitcore_rust_future_complete_void(future, continuation) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_free_void(future) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_cancel_void(future) }, + // lift function + { Unit }, + + // Error FFI converter + PaykitExceptionErrorHandler, + ) + } + + + + + + + + public companion object + +} + + + + + +public object FfiConverterTypePubkyAuthenticatedTransport: FfiConverter { + + override fun lower(value: PubkyAuthenticatedTransport): Pointer { + return value.uniffiClonePointer() + } + + override fun lift(value: Pointer): PubkyAuthenticatedTransport { + return PubkyAuthenticatedTransport(value) + } + + override fun read(buf: ByteBuffer): PubkyAuthenticatedTransport { + // The Rust code always writes pointers as 8 bytes, and will + // fail to compile if they don't fit. + return lift(buf.getLong().toPointer()) + } + + override fun allocationSize(value: PubkyAuthenticatedTransport): ULong = 8UL + + override fun write(value: PubkyAuthenticatedTransport, buf: ByteBuffer) { + // The Rust code always expects pointers written as 8 bytes, + // and will fail to compile if they don't fit. + buf.putLong(lower(value).toLong()) + } +} + + + +/** + * Unauthenticated transport wrapper for Paykit read operations. + */ +public open class PubkyUnauthenticatedTransport: Disposable, PubkyUnauthenticatedTransportInterface { + + public constructor(pointer: Pointer) { + this.pointer = pointer + this.cleanable = UniffiLib.CLEANER.register(this, UniffiPointerDestroyer(pointer)) + } + + /** + * This constructor can be used to instantiate a fake object. Only used for tests. Any + * attempt to actually use an object constructed this way will fail as there is no + * connected Rust object. + */ + public constructor(noPointer: NoPointer) { + this.pointer = null + this.cleanable = UniffiLib.CLEANER.register(this, UniffiPointerDestroyer(null)) + } + /** + * Creates a new unauthenticated transport for reading public payment data. + */ + public constructor() : this( + uniffiRustCallWithError(PaykitExceptionErrorHandler) { uniffiRustCallStatus -> + UniffiLib.uniffi_bitkitcore_fn_constructor_pubkyunauthenticatedtransport_new( + uniffiRustCallStatus, + ) + }!! + ) + + protected val pointer: Pointer? + protected val cleanable: UniffiCleaner.Cleanable + + private val wasDestroyed: kotlinx.atomicfu.AtomicBoolean = kotlinx.atomicfu.atomic(false) + private val callCounter: kotlinx.atomicfu.AtomicLong = kotlinx.atomicfu.atomic(1L) + + private val lock = kotlinx.atomicfu.locks.ReentrantLock() + + private fun synchronized(block: () -> T): T { + lock.lock() + try { + return block() + } finally { + lock.unlock() + } + } + + override fun destroy() { + // Only allow a single call to this method. + // TODO: maybe we should log a warning if called more than once? + if (this.wasDestroyed.compareAndSet(false, true)) { + // This decrement always matches the initial count of 1 given at creation time. + if (this.callCounter.decrementAndGet() == 0L) { + cleanable.clean() + } + } + } + + override fun close() { + synchronized { this.destroy() } + } + + internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { + // Check and increment the call counter, to keep the object alive. + // This needs a compare-and-set retry loop in case of concurrent updates. + do { + val c = this.callCounter.value + if (c == 0L) { + throw IllegalStateException("${this::class::simpleName} object has already been destroyed") + } + if (c == Long.MAX_VALUE) { + throw IllegalStateException("${this::class::simpleName} call counter would overflow") + } + } while (! this.callCounter.compareAndSet(c, c + 1L)) + // Now we can safely do the method call without the pointer being freed concurrently. + try { + return block(this.uniffiClonePointer()) + } finally { + // This decrement always matches the increment we performed above. + if (this.callCounter.decrementAndGet() == 0L) { + cleanable.clean() + } + } + } + + // Use a static inner class instead of a closure so as not to accidentally + // capture `this` as part of the cleanable's action. + private class UniffiPointerDestroyer(private val pointer: Pointer?) : Disposable { + override fun destroy() { + pointer?.let { ptr -> + uniffiRustCall { status -> + UniffiLib.uniffi_bitkitcore_fn_free_pubkyunauthenticatedtransport(ptr, status) + } + } + } } -} + public fun uniffiClonePointer(): Pointer { + return uniffiRustCall { status -> + UniffiLib.uniffi_bitkitcore_fn_clone_pubkyunauthenticatedtransport(pointer!!, status) + }!! + } -public object FfiConverterBoolean: FfiConverter { - override fun lift(value: Byte): Boolean { - return value.toInt() != 0 + + /** + * Returns known contacts (follows) of a given public key. + * + * # Parameters + * - `key`: Public key to query for contacts + * + * # Returns + * - `Ok(Vec)` with list of known contacts + * - Returns empty vector if no contacts are stored + * - `Err` only on transport failures + */ + @Throws(PaykitException::class, kotlin.coroutines.cancellation.CancellationException::class) + public override suspend fun `getKnownContacts`(`key`: PublicKey): List { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_known_contacts( + thisPtr, + FfiConverterTypePublicKey.lower(`key`), + ) + }, + { future, callback, continuation -> UniffiLib.ffi_bitkitcore_rust_future_poll_rust_buffer(future, callback, continuation) }, + { future, continuation -> UniffiLib.ffi_bitkitcore_rust_future_complete_rust_buffer(future, continuation) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_free_rust_buffer(future) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_cancel_rust_buffer(future) }, + // lift function + { FfiConverterSequenceTypePublicKey.lift(it) }, + // Error FFI converter + PaykitExceptionErrorHandler, + ) } - override fun read(buf: ByteBuffer): Boolean { - return lift(buf.get()) + /** + * Retrieves a specific payment endpoint for a payee and method. + * + * # Parameters + * - `payee`: Public key of the payee + * - `method`: Payment method identifier to query + * + * # Returns + * - `Ok(Some(EndpointData))` if the endpoint exists + * - `Ok(None)` if the endpoint is not published + * - `Err` only on transport failures + */ + @Throws(PaykitException::class, kotlin.coroutines.cancellation.CancellationException::class) + public override suspend fun `getPaymentEndpoint`(`payee`: PublicKey, `method`: MethodId): EndpointData? { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_endpoint( + thisPtr, + FfiConverterTypePublicKey.lower(`payee`), + FfiConverterTypeMethodId.lower(`method`), + ) + }, + { future, callback, continuation -> UniffiLib.ffi_bitkitcore_rust_future_poll_rust_buffer(future, callback, continuation) }, + { future, continuation -> UniffiLib.ffi_bitkitcore_rust_future_complete_rust_buffer(future, continuation) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_free_rust_buffer(future) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_cancel_rust_buffer(future) }, + // lift function + { FfiConverterOptionalTypeEndpointData.lift(it) }, + // Error FFI converter + PaykitExceptionErrorHandler, + ) } - override fun lower(value: Boolean): Byte { - return if (value) 1.toByte() else 0.toByte() + /** + * Retrieves all supported payment methods for a given payee. + * + * # Parameters + * - `payee`: Public key of the payee to query + * + * # Returns + * - `Ok(SupportedPayments)` with map of method IDs to endpoint data + * - Returns empty map if no endpoints are published + * - `Err` only on transport failures + */ + @Throws(PaykitException::class, kotlin.coroutines.cancellation.CancellationException::class) + public override suspend fun `getPaymentList`(`payee`: PublicKey): SupportedPayments { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_list( + thisPtr, + FfiConverterTypePublicKey.lower(`payee`), + ) + }, + { future, callback, continuation -> UniffiLib.ffi_bitkitcore_rust_future_poll_rust_buffer(future, callback, continuation) }, + { future, continuation -> UniffiLib.ffi_bitkitcore_rust_future_complete_rust_buffer(future, continuation) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_free_rust_buffer(future) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_cancel_rust_buffer(future) }, + // lift function + { FfiConverterTypeSupportedPayments.lift(it) }, + // Error FFI converter + PaykitExceptionErrorHandler, + ) } - override fun allocationSize(value: Boolean): ULong = 1UL - override fun write(value: Boolean, buf: ByteBuffer) { - buf.put(lower(value)) - } + + + + + + public companion object + } -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: RustBufferByValue): String { - try { - require(value.len <= Int.MAX_VALUE) { - val length = value.len - "cannot handle RustBuffer longer than Int.MAX_VALUE bytes: length is $length" - } - val byteArr = value.asByteBuffer()!!.get(value.len.toInt()) - return byteArr.decodeToString() - } finally { - RustBufferHelper.free(value) - } - } - override fun read(buf: ByteBuffer): String { - val len = buf.getInt() - val byteArr = buf.get(len) - return byteArr.decodeToString() - } - override fun lower(value: String): RustBufferByValue { - // TODO: prevent allocating a new byte array here - val encoded = value.encodeToByteArray(throwOnInvalidSequence = true) - return RustBufferHelper.allocValue(encoded.size.toULong()).apply { - asByteBuffer()!!.put(encoded) - } + +public object FfiConverterTypePubkyUnauthenticatedTransport: FfiConverter { + + override fun lower(value: PubkyUnauthenticatedTransport): Pointer { + return value.uniffiClonePointer() } - // 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 lift(value: Pointer): PubkyUnauthenticatedTransport { + return PubkyUnauthenticatedTransport(value) } - override fun write(value: String, buf: ByteBuffer) { - // TODO: prevent allocating a new byte array here - val encoded = value.encodeToByteArray(throwOnInvalidSequence = true) - buf.putInt(encoded.size) - buf.put(encoded) + override fun read(buf: ByteBuffer): PubkyUnauthenticatedTransport { + // The Rust code always writes pointers as 8 bytes, and will + // fail to compile if they don't fit. + return lift(buf.getLong().toPointer()) } -} + override fun allocationSize(value: PubkyUnauthenticatedTransport): ULong = 8UL -public object FfiConverterByteArray: FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): ByteArray { - val len = buf.getInt() - val byteArr = buf.get(len) - 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) + override fun write(value: PubkyUnauthenticatedTransport, buf: ByteBuffer) { + // The Rust code always expects pointers written as 8 bytes, + // and will fail to compile if they don't fit. + buf.putLong(lower(value).toLong()) } } @@ -3261,6 +4079,25 @@ public object FfiConverterTypeDeviceParams: FfiConverterRustBuffer +public object FfiConverterTypeEndpointData: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): EndpointData { + return EndpointData( + FfiConverterString.read(buf), + ) + } + + override fun allocationSize(value: EndpointData): ULong = ( + FfiConverterString.allocationSize(value.`data`) + ) + + override fun write(value: EndpointData, buf: ByteBuffer) { + FfiConverterString.write(value.`data`, buf) + } +} + + + + public object FfiConverterTypeErrorData: FfiConverterRustBuffer { override fun read(buf: ByteBuffer): ErrorData { return ErrorData( @@ -4761,6 +5598,25 @@ public object FfiConverterTypeMessageSignatureResponse: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): MethodId { + return MethodId( + FfiConverterString.read(buf), + ) + } + + override fun allocationSize(value: MethodId): ULong = ( + FfiConverterString.allocationSize(value.`id`) + ) + + override fun write(value: MethodId, buf: ByteBuffer) { + FfiConverterString.write(value.`id`, buf) + } +} + + + + public object FfiConverterTypeMultisigRedeemScriptType: FfiConverterRustBuffer { override fun read(buf: ByteBuffer): MultisigRedeemScriptType { return MultisigRedeemScriptType( @@ -4893,6 +5749,31 @@ public object FfiConverterTypeOnchainActivity: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): PaykitDeeplink { + return PaykitDeeplink( + FfiConverterString.read(buf), + FfiConverterOptionalString.read(buf), + FfiConverterMapStringString.read(buf), + ) + } + + override fun allocationSize(value: PaykitDeeplink): ULong = ( + FfiConverterString.allocationSize(value.`action`) + + FfiConverterOptionalString.allocationSize(value.`sessionToken`) + + FfiConverterMapStringString.allocationSize(value.`parameters`) + ) + + override fun write(value: PaykitDeeplink, buf: ByteBuffer) { + FfiConverterString.write(value.`action`, buf) + FfiConverterOptionalString.write(value.`sessionToken`, buf) + FfiConverterMapStringString.write(value.`parameters`, buf) + } +} + + + + public object FfiConverterTypePaymentRequestMemo: FfiConverterRustBuffer { override fun read(buf: ByteBuffer): PaymentRequestMemo { return PaymentRequestMemo( @@ -5082,6 +5963,25 @@ public object FfiConverterTypePubkyAuth: FfiConverterRustBuffer { +public object FfiConverterTypePublicKey: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): PublicKey { + return PublicKey( + FfiConverterString.read(buf), + ) + } + + override fun allocationSize(value: PublicKey): ULong = ( + FfiConverterString.allocationSize(value.`key`) + ) + + override fun write(value: PublicKey, buf: ByteBuffer) { + FfiConverterString.write(value.`key`, buf) + } +} + + + + public object FfiConverterTypePublicKeyResponse: FfiConverterRustBuffer { override fun read(buf: ByteBuffer): PublicKeyResponse { return PublicKeyResponse( @@ -5249,6 +6149,84 @@ public object FfiConverterTypeRefundMemo: FfiConverterRustBuffer { +public object FfiConverterTypeScannedPaykitSession: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): ScannedPaykitSession { + return ScannedPaykitSession( + FfiConverterString.read(buf), + FfiConverterString.read(buf), + FfiConverterString.read(buf), + FfiConverterMapStringString.read(buf), + ) + } + + override fun allocationSize(value: ScannedPaykitSession): ULong = ( + FfiConverterString.allocationSize(value.`url`) + + FfiConverterString.allocationSize(value.`action`) + + FfiConverterString.allocationSize(value.`token`) + + FfiConverterMapStringString.allocationSize(value.`parameters`) + ) + + override fun write(value: ScannedPaykitSession, buf: ByteBuffer) { + FfiConverterString.write(value.`url`, buf) + FfiConverterString.write(value.`action`, buf) + FfiConverterString.write(value.`token`, buf) + FfiConverterMapStringString.write(value.`parameters`, buf) + } +} + + + + +public object FfiConverterTypeSessionData: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): SessionData { + return SessionData( + FfiConverterString.read(buf), + FfiConverterString.read(buf), + FfiConverterOptionalString.read(buf), + FfiConverterOptionalLong.read(buf), + FfiConverterOptionalString.read(buf), + ) + } + + override fun allocationSize(value: SessionData): ULong = ( + FfiConverterString.allocationSize(value.`publicKey`) + + FfiConverterString.allocationSize(value.`secretKey`) + + FfiConverterOptionalString.allocationSize(value.`homeserverUrl`) + + FfiConverterOptionalLong.allocationSize(value.`expiresAt`) + + FfiConverterOptionalString.allocationSize(value.`metadata`) + ) + + override fun write(value: SessionData, buf: ByteBuffer) { + FfiConverterString.write(value.`publicKey`, buf) + FfiConverterString.write(value.`secretKey`, buf) + FfiConverterOptionalString.write(value.`homeserverUrl`, buf) + FfiConverterOptionalLong.write(value.`expiresAt`, buf) + FfiConverterOptionalString.write(value.`metadata`, buf) + } +} + + + + +public object FfiConverterTypeSessionToken: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): SessionToken { + return SessionToken( + FfiConverterString.read(buf), + ) + } + + override fun allocationSize(value: SessionToken): ULong = ( + FfiConverterString.allocationSize(value.`token`) + ) + + override fun write(value: SessionToken, buf: ByteBuffer) { + FfiConverterString.write(value.`token`, buf) + } +} + + + + public object FfiConverterTypeSignedTransactionResponse: FfiConverterRustBuffer { override fun read(buf: ByteBuffer): SignedTransactionResponse { return SignedTransactionResponse( @@ -5274,6 +6252,25 @@ public object FfiConverterTypeSignedTransactionResponse: FfiConverterRustBuffer< +public object FfiConverterTypeSupportedPayments: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): SupportedPayments { + return SupportedPayments( + FfiConverterMapStringTypeEndpointData.read(buf), + ) + } + + override fun allocationSize(value: SupportedPayments): ULong = ( + FfiConverterMapStringTypeEndpointData.allocationSize(value.`entries`) + ) + + override fun write(value: SupportedPayments, buf: ByteBuffer) { + FfiConverterMapStringTypeEndpointData.write(value.`entries`, buf) + } +} + + + + public object FfiConverterTypeTextMemo: FfiConverterRustBuffer { override fun read(buf: ByteBuffer): TextMemo { return TextMemo( @@ -6789,6 +7786,109 @@ public object FfiConverterTypeNetworkType: FfiConverterRustBuffer { +public object PaykitExceptionErrorHandler : UniffiRustCallStatusErrorHandler { + override fun lift(errorBuf: RustBufferByValue): PaykitException = FfiConverterTypePaykitError.lift(errorBuf) +} + +public object FfiConverterTypePaykitError : FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): PaykitException { + return when (buf.getInt()) { + 1 -> PaykitException.Unimplemented( + FfiConverterString.read(buf), + ) + 2 -> PaykitException.Transport( + FfiConverterString.read(buf), + ) + 3 -> PaykitException.InvalidPublicKey( + FfiConverterString.read(buf), + ) + 4 -> PaykitException.InvalidMethodId( + FfiConverterString.read(buf), + ) + 5 -> PaykitException.InvalidEndpointData( + FfiConverterString.read(buf), + ) + 6 -> PaykitException.SessionException( + FfiConverterString.read(buf), + ) + else -> throw RuntimeException("invalid error enum value, something is very wrong!!") + } + } + + override fun allocationSize(value: PaykitException): ULong { + return when (value) { + is PaykitException.Unimplemented -> ( + // Add the size for the Int that specifies the variant plus the size needed for all fields + 4UL + + FfiConverterString.allocationSize(value.v1) + ) + is PaykitException.Transport -> ( + // Add the size for the Int that specifies the variant plus the size needed for all fields + 4UL + + FfiConverterString.allocationSize(value.v1) + ) + is PaykitException.InvalidPublicKey -> ( + // Add the size for the Int that specifies the variant plus the size needed for all fields + 4UL + + FfiConverterString.allocationSize(value.v1) + ) + is PaykitException.InvalidMethodId -> ( + // Add the size for the Int that specifies the variant plus the size needed for all fields + 4UL + + FfiConverterString.allocationSize(value.v1) + ) + is PaykitException.InvalidEndpointData -> ( + // Add the size for the Int that specifies the variant plus the size needed for all fields + 4UL + + FfiConverterString.allocationSize(value.v1) + ) + is PaykitException.SessionException -> ( + // Add the size for the Int that specifies the variant plus the size needed for all fields + 4UL + + FfiConverterString.allocationSize(value.v1) + ) + } + } + + override fun write(value: PaykitException, buf: ByteBuffer) { + when (value) { + is PaykitException.Unimplemented -> { + buf.putInt(1) + FfiConverterString.write(value.v1, buf) + Unit + } + is PaykitException.Transport -> { + buf.putInt(2) + FfiConverterString.write(value.v1, buf) + Unit + } + is PaykitException.InvalidPublicKey -> { + buf.putInt(3) + FfiConverterString.write(value.v1, buf) + Unit + } + is PaykitException.InvalidMethodId -> { + buf.putInt(4) + FfiConverterString.write(value.v1, buf) + Unit + } + is PaykitException.InvalidEndpointData -> { + buf.putInt(5) + FfiConverterString.write(value.v1, buf) + Unit + } + is PaykitException.SessionException -> { + buf.putInt(6) + FfiConverterString.write(value.v1, buf) + Unit + } + }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ } + } +} + + + + public object FfiConverterTypePaymentState: FfiConverterRustBuffer { override fun read(buf: ByteBuffer): PaymentState = try { @@ -6838,26 +7938,29 @@ public object FfiConverterTypeScanner : FfiConverterRustBuffer{ 3 -> Scanner.PubkyAuth( FfiConverterString.read(buf), ) - 4 -> Scanner.LnurlChannel( + 4 -> Scanner.PaykitSession( + FfiConverterTypeScannedPaykitSession.read(buf), + ) + 5 -> Scanner.LnurlChannel( FfiConverterTypeLnurlChannelData.read(buf), ) - 5 -> Scanner.LnurlAuth( + 6 -> Scanner.LnurlAuth( FfiConverterTypeLnurlAuthData.read(buf), ) - 6 -> Scanner.LnurlWithdraw( + 7 -> Scanner.LnurlWithdraw( FfiConverterTypeLnurlWithdrawData.read(buf), ) - 7 -> Scanner.LnurlAddress( + 8 -> Scanner.LnurlAddress( FfiConverterTypeLnurlAddressData.read(buf), ) - 8 -> Scanner.LnurlPay( + 9 -> Scanner.LnurlPay( FfiConverterTypeLnurlPayData.read(buf), ) - 9 -> Scanner.NodeId( + 10 -> Scanner.NodeId( FfiConverterString.read(buf), FfiConverterTypeNetworkType.read(buf), ) - 10 -> Scanner.Gift( + 11 -> Scanner.Gift( FfiConverterString.read(buf), FfiConverterULong.read(buf), ) @@ -6887,6 +7990,13 @@ public object FfiConverterTypeScanner : FfiConverterRustBuffer{ + FfiConverterString.allocationSize(value.`data`) ) } + is Scanner.PaykitSession -> { + // Add the size for the Int that specifies the variant plus the size needed for all fields + ( + 4UL + + FfiConverterTypeScannedPaykitSession.allocationSize(value.`data`) + ) + } is Scanner.LnurlChannel -> { // Add the size for the Int that specifies the variant plus the size needed for all fields ( @@ -6957,39 +8067,44 @@ public object FfiConverterTypeScanner : FfiConverterRustBuffer{ FfiConverterString.write(value.`data`, buf) Unit } - is Scanner.LnurlChannel -> { + is Scanner.PaykitSession -> { buf.putInt(4) + FfiConverterTypeScannedPaykitSession.write(value.`data`, buf) + Unit + } + is Scanner.LnurlChannel -> { + buf.putInt(5) FfiConverterTypeLnurlChannelData.write(value.`data`, buf) Unit } is Scanner.LnurlAuth -> { - buf.putInt(5) + buf.putInt(6) FfiConverterTypeLnurlAuthData.write(value.`data`, buf) Unit } is Scanner.LnurlWithdraw -> { - buf.putInt(6) + buf.putInt(7) FfiConverterTypeLnurlWithdrawData.write(value.`data`, buf) Unit } is Scanner.LnurlAddress -> { - buf.putInt(7) + buf.putInt(8) FfiConverterTypeLnurlAddressData.write(value.`data`, buf) Unit } is Scanner.LnurlPay -> { - buf.putInt(8) + buf.putInt(9) FfiConverterTypeLnurlPayData.write(value.`data`, buf) Unit } is Scanner.NodeId -> { - buf.putInt(9) + buf.putInt(10) FfiConverterString.write(value.`url`, buf) FfiConverterTypeNetworkType.write(value.`network`, buf) Unit } is Scanner.Gift -> { - buf.putInt(10) + buf.putInt(11) FfiConverterString.write(value.`code`, buf) FfiConverterULong.write(value.`amount`, buf) Unit @@ -7408,6 +8523,35 @@ public object FfiConverterOptionalULong: FfiConverterRustBuffer { +public object FfiConverterOptionalLong: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): kotlin.Long? { + if (buf.get().toInt() == 0) { + return null + } + return FfiConverterLong.read(buf) + } + + override fun allocationSize(value: kotlin.Long?): ULong { + if (value == null) { + return 1UL + } else { + return 1UL + FfiConverterLong.allocationSize(value) + } + } + + override fun write(value: kotlin.Long?, buf: ByteBuffer) { + if (value == null) { + buf.put(0) + } else { + buf.put(1) + FfiConverterLong.write(value, buf) + } + } +} + + + + public object FfiConverterOptionalBoolean: FfiConverterRustBuffer { override fun read(buf: ByteBuffer): kotlin.Boolean? { if (buf.get().toInt() == 0) { @@ -7698,6 +8842,35 @@ public object FfiConverterOptionalTypeDeviceParams: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): EndpointData? { + if (buf.get().toInt() == 0) { + return null + } + return FfiConverterTypeEndpointData.read(buf) + } + + override fun allocationSize(value: EndpointData?): ULong { + if (value == null) { + return 1UL + } else { + return 1UL + FfiConverterTypeEndpointData.allocationSize(value) + } + } + + override fun write(value: EndpointData?, buf: ByteBuffer) { + if (value == null) { + buf.put(0) + } else { + buf.put(1) + FfiConverterTypeEndpointData.write(value, buf) + } + } +} + + + + public object FfiConverterOptionalTypeIBtBolt11Invoice: FfiConverterRustBuffer { override fun read(buf: ByteBuffer): IBtBolt11Invoice? { if (buf.get().toInt() == 0) { @@ -9611,6 +10784,31 @@ public object FfiConverterSequenceTypePrecomposedTransaction: FfiConverterRustBu +public object FfiConverterSequenceTypePublicKey: FfiConverterRustBuffer> { + override fun read(buf: ByteBuffer): List { + val len = buf.getInt() + return List(len) { + FfiConverterTypePublicKey.read(buf) + } + } + + override fun allocationSize(value: List): ULong { + val sizeForLength = 4UL + val sizeForItems = value.sumOf { FfiConverterTypePublicKey.allocationSize(it) } + return sizeForLength + sizeForItems + } + + override fun write(value: List, buf: ByteBuffer) { + buf.putInt(value.size) + value.iterator().forEach { + FfiConverterTypePublicKey.write(it, buf) + } + } +} + + + + public object FfiConverterSequenceTypeRefTransaction: FfiConverterRustBuffer> { override fun read(buf: ByteBuffer): List { val len = buf.getInt() @@ -9845,6 +11043,41 @@ public object FfiConverterMapStringString: FfiConverterRustBuffer> { + override fun read(buf: ByteBuffer): Map { + val len = buf.getInt() + return buildMap(len) { + repeat(len) { + val k = FfiConverterString.read(buf) + val v = FfiConverterTypeEndpointData.read(buf) + this[k] = v + } + } + } + + override fun allocationSize(value: Map): ULong { + val spaceForMapSize = 4UL + val spaceForChildren = value.entries.sumOf { (k, v) -> + FfiConverterString.allocationSize(k) + + FfiConverterTypeEndpointData.allocationSize(v) + } + return spaceForMapSize + spaceForChildren + } + + override fun write(value: Map, buf: ByteBuffer) { + buf.putInt(value.size) + // The parens on `(k, v)` here ensure we're calling the right method, + // which is important for compatibility with older android devices. + // Ref https://blog.danlew.net/2017/03/16/kotlin-puzzler-whose-line-is-it-anyways/ + value.forEach { (k, v) -> + FfiConverterString.write(k, buf) + FfiConverterTypeEndpointData.write(v, buf) + } + } +} + + + @@ -9991,6 +11224,42 @@ public suspend fun `createCjitEntry`(`channelSizeSat`: kotlin.ULong, `invoiceSat ) } +/** + * Creates a deeplink URL from a session token. + * + * Use this to generate a deeplink that can be shared with another app instance. + * + * # Example + * ``` + * let token = create_session_token_from_keypair( + * public_key, + * secret_key, + * None, + * Some(3600) + * )?; + * + * let deeplink_url = create_deeplink_from_token( + * "myapp://", + * "session", + * token, + * None + * )?; + * // Result: "myapp://paykit/session?token=..." + * ``` + */ +@Throws(PaykitException::class) +public fun `createDeeplinkFromToken`(`baseUrl`: kotlin.String, `action`: kotlin.String, `token`: SessionToken, `additionalParams`: Map?): kotlin.String { + return FfiConverterString.lift(uniffiRustCallWithError(PaykitExceptionErrorHandler) { uniffiRustCallStatus -> + UniffiLib.uniffi_bitkitcore_fn_func_create_deeplink_from_token( + FfiConverterString.lower(`baseUrl`), + FfiConverterString.lower(`action`), + FfiConverterTypeSessionToken.lower(`token`), + FfiConverterOptionalMapStringString.lower(`additionalParams`), + uniffiRustCallStatus, + ) + }) +} + @Throws(BlocktankException::class, kotlin.coroutines.cancellation.CancellationException::class) public suspend fun `createOrder`(`lspBalanceSat`: kotlin.ULong, `channelExpiryWeeks`: kotlin.UInt, `options`: CreateOrderOptions?): IBtOrder { return uniffiRustCallAsync( @@ -10010,6 +11279,68 @@ public suspend fun `createOrder`(`lspBalanceSat`: kotlin.ULong, `channelExpiryWe ) } +/** + * Creates a session request URL to send to Pubky Ring for authentication. + * + * This generates a URL that Bitkit displays as a QR code or uses to open Pubky Ring. + * When Pubky Ring completes authentication, it will return the session data + * via the provided callback URL. + * + * # Parameters + * - `callback_url`: The URL scheme and path where Pubky Ring should return the session. + * Example: "bitkit://paykit/session-data" or "bitkit://session" + * - `additional_params`: Optional additional parameters to include in the request URL + * + * # Returns + * A URL string like: `pubkyring://session?callback=bitkit%3A%2F%2Fpaykit%2Fsession-data` + * + * # Example + * ``` + * // Generate URL for QR code or "Open Pubky Ring" button + * let request_url = create_pubky_ring_session_request( + * "bitkit://paykit/session-data".to_string(), + * None + * )?; + * // Result: "pubkyring://session?callback=bitkit%3A%2F%2Fpaykit%2Fsession-data" + * + * // With additional parameters + * let mut params = HashMap::new(); + * params.insert("app_name".to_string(), "Bitkit".to_string()); + * let request_url = create_pubky_ring_session_request( + * "bitkit://paykit/session-data".to_string(), + * Some(params) + * )?; + * ``` + */ +@Throws(PaykitException::class) +public fun `createPubkyRingSessionRequest`(`callbackUrl`: kotlin.String, `additionalParams`: Map?): kotlin.String { + return FfiConverterString.lift(uniffiRustCallWithError(PaykitExceptionErrorHandler) { uniffiRustCallStatus -> + UniffiLib.uniffi_bitkitcore_fn_func_create_pubky_ring_session_request( + FfiConverterString.lower(`callbackUrl`), + FfiConverterOptionalMapStringString.lower(`additionalParams`), + uniffiRustCallStatus, + ) + }) +} + +/** + * Helper function to create a session token from raw keypair data. + * + * This is useful when you have the keypair but need to create a shareable token. + */ +@Throws(PaykitException::class) +public fun `createSessionTokenFromKeypair`(`publicKey`: kotlin.String, `secretKey`: kotlin.String, `homeserverUrl`: kotlin.String?, `expiresInSeconds`: kotlin.Long?): SessionToken { + return FfiConverterTypeSessionToken.lift(uniffiRustCallWithError(PaykitExceptionErrorHandler) { uniffiRustCallStatus -> + UniffiLib.uniffi_bitkitcore_fn_func_create_session_token_from_keypair( + FfiConverterString.lower(`publicKey`), + FfiConverterString.lower(`secretKey`), + FfiConverterOptionalString.lower(`homeserverUrl`), + FfiConverterOptionalLong.lower(`expiresInSeconds`), + uniffiRustCallStatus, + ) + }) +} + @Throws(LnurlException::class) public fun `createWithdrawCallbackUrl`(`k1`: kotlin.String, `callback`: kotlin.String, `paymentRequest`: kotlin.String): kotlin.String { return FfiConverterString.lift(uniffiRustCallWithError(LnurlExceptionErrorHandler) { uniffiRustCallStatus -> @@ -10101,6 +11432,26 @@ public fun `derivePrivateKey`(`mnemonicPhrase`: kotlin.String, `derivationPathSt }) } +/** + * Deserializes a session token back into session data. + * + * # Example + * ``` + * let token = SessionToken::new("base64_encoded_session_data"); + * let session_data = deserialize_token_to_session(token)?; + * // Now you have the session data back + * ``` + */ +@Throws(PaykitException::class) +public fun `deserializeTokenToSession`(`token`: SessionToken): SessionData { + return FfiConverterTypeSessionData.lift(uniffiRustCallWithError(PaykitExceptionErrorHandler) { uniffiRustCallStatus -> + UniffiLib.uniffi_bitkitcore_fn_func_deserialize_token_to_session( + FfiConverterTypeSessionToken.lower(`token`), + uniffiRustCallStatus, + ) + }) +} + @Throws(AddressException::class) public fun `entropyToMnemonic`(`entropy`: kotlin.ByteArray): kotlin.String { return FfiConverterString.lift(uniffiRustCallWithError(AddressExceptionErrorHandler) { uniffiRustCallStatus -> @@ -10335,6 +11686,46 @@ public suspend fun `getInfo`(`refresh`: kotlin.Boolean?): IBtInfo? { ) } +/** + * Returns known contacts (follows) of a given public key. + * + * # Parameters + * - `reader`: Unauthenticated transport for reading public data + * - `key`: Public key to query for contacts + * + * # Returns + * - `Ok(Vec)` with list of known contacts + * - Returns empty vector if no contacts are stored + * - `Err` only on transport failures + * + * # Example + * ``` + * let reader = PubkyUnauthenticatedTransport::new()?; + * let user = PublicKey { key: "...".to_string() }; + * let contacts = get_known_contacts(&reader, &user).await?; + * for contact in contacts { + * println!("Contact: {}", contact.key); + * } + * ``` + */ +@Throws(PaykitException::class, kotlin.coroutines.cancellation.CancellationException::class) +public suspend fun `getKnownContacts`(`reader`: PubkyUnauthenticatedTransport, `key`: PublicKey): List { + return uniffiRustCallAsync( + UniffiLib.uniffi_bitkitcore_fn_func_get_known_contacts( + FfiConverterTypePubkyUnauthenticatedTransport.lower(`reader`), + FfiConverterTypePublicKey.lower(`key`), + ), + { future, callback, continuation -> UniffiLib.ffi_bitkitcore_rust_future_poll_rust_buffer(future, callback, continuation) }, + { future, continuation -> UniffiLib.ffi_bitkitcore_rust_future_complete_rust_buffer(future, continuation) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_free_rust_buffer(future) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_cancel_rust_buffer(future) }, + // lift function + { FfiConverterSequenceTypePublicKey.lift(it) }, + // Error FFI converter + PaykitExceptionErrorHandler, + ) +} + @Throws(LnurlException::class, kotlin.coroutines.cancellation.CancellationException::class) public suspend fun `getLnurlInvoice`(`address`: kotlin.String, `amountSatoshis`: kotlin.ULong): kotlin.String { return uniffiRustCallAsync( @@ -10406,6 +11797,88 @@ public suspend fun `getPayment`(`paymentId`: kotlin.String): IBtBolt11Invoice { ) } +/** + * Retrieves a specific payment endpoint for a payee and method. + * + * # Parameters + * - `reader`: Unauthenticated transport for reading public data + * - `payee`: Public key of the payee + * - `method`: Payment method identifier to query + * + * # Returns + * - `Ok(Some(EndpointData))` if the endpoint exists + * - `Ok(None)` if the endpoint is not published + * - `Err` only on transport failures + * + * # Example + * ``` + * let reader = PubkyUnauthenticatedTransport::new()?; + * let payee = PublicKey { key: "...".to_string() }; + * let method = MethodId { id: "lightning".to_string() }; + * if let Some(endpoint) = get_payment_endpoint(&reader, &payee, &method).await? { + * println!("Lightning endpoint: {}", endpoint.data); + * } + * ``` + */ +@Throws(PaykitException::class, kotlin.coroutines.cancellation.CancellationException::class) +public suspend fun `getPaymentEndpoint`(`reader`: PubkyUnauthenticatedTransport, `payee`: PublicKey, `method`: MethodId): EndpointData? { + return uniffiRustCallAsync( + UniffiLib.uniffi_bitkitcore_fn_func_get_payment_endpoint( + FfiConverterTypePubkyUnauthenticatedTransport.lower(`reader`), + FfiConverterTypePublicKey.lower(`payee`), + FfiConverterTypeMethodId.lower(`method`), + ), + { future, callback, continuation -> UniffiLib.ffi_bitkitcore_rust_future_poll_rust_buffer(future, callback, continuation) }, + { future, continuation -> UniffiLib.ffi_bitkitcore_rust_future_complete_rust_buffer(future, continuation) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_free_rust_buffer(future) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_cancel_rust_buffer(future) }, + // lift function + { FfiConverterOptionalTypeEndpointData.lift(it) }, + // Error FFI converter + PaykitExceptionErrorHandler, + ) +} + +/** + * Retrieves all supported payment methods for a given payee. + * + * # Parameters + * - `reader`: Unauthenticated transport for reading public data + * - `payee`: Public key of the payee to query + * + * # Returns + * - `Ok(SupportedPayments)` with map of method IDs to endpoint data + * - Returns empty map if no endpoints are published + * - `Err` only on transport failures + * + * # Example + * ``` + * let reader = PubkyUnauthenticatedTransport::new()?; + * let payee = PublicKey { key: "...".to_string() }; + * let payments = get_payment_list(&reader, &payee).await?; + * for (method_id, data) in payments.entries { + * println!("Method: {}, Data: {}", method_id, data.data); + * } + * ``` + */ +@Throws(PaykitException::class, kotlin.coroutines.cancellation.CancellationException::class) +public suspend fun `getPaymentList`(`reader`: PubkyUnauthenticatedTransport, `payee`: PublicKey): SupportedPayments { + return uniffiRustCallAsync( + UniffiLib.uniffi_bitkitcore_fn_func_get_payment_list( + FfiConverterTypePubkyUnauthenticatedTransport.lower(`reader`), + FfiConverterTypePublicKey.lower(`payee`), + ), + { future, callback, continuation -> UniffiLib.ffi_bitkitcore_rust_future_poll_rust_buffer(future, callback, continuation) }, + { future, continuation -> UniffiLib.ffi_bitkitcore_rust_future_complete_rust_buffer(future, continuation) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_free_rust_buffer(future) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_cancel_rust_buffer(future) }, + // lift function + { FfiConverterTypeSupportedPayments.lift(it) }, + // Error FFI converter + PaykitExceptionErrorHandler, + ) +} + @Throws(ActivityException::class) public fun `getPreActivityMetadata`(`searchKey`: kotlin.String, `searchByAddress`: kotlin.Boolean): PreActivityMetadata? { return FfiConverterOptionalTypePreActivityMetadata.lift(uniffiRustCallWithError(ActivityExceptionErrorHandler) { uniffiRustCallStatus -> @@ -10562,6 +12035,32 @@ public suspend fun `openChannel`(`orderId`: kotlin.String, `connectionString`: k ) } +/** + * Parses a deeplink URL into a PaykitDeeplink structure. + * + * # Supported URL Formats + * - `myapp://paykit/session?token=` + * - `myapp://paykit/connect?token=&return_url=` + * - `https://myapp.com/paykit/session?token=` + * + * # Example + * ``` + * let url = "myapp://paykit/session?token=eyJwdWJsaWNfa2V5IjoiLi4uIn0"; + * let deeplink = parse_paykit_deeplink(url)?; + * assert_eq!(deeplink.action, "session"); + * assert!(deeplink.session_token.is_some()); + * ``` + */ +@Throws(PaykitException::class) +public fun `parsePaykitDeeplink`(`url`: kotlin.String): PaykitDeeplink { + return FfiConverterTypePaykitDeeplink.lift(uniffiRustCallWithError(PaykitExceptionErrorHandler) { uniffiRustCallStatus -> + UniffiLib.uniffi_bitkitcore_fn_func_parse_paykit_deeplink( + FfiConverterString.lower(`url`), + uniffiRustCallStatus, + ) + }) +} + /** * Refresh all active CJIT entries in the database with latest data from the LSP */ @@ -10724,6 +12223,36 @@ public fun `removeClosedChannelById`(`channelId`: kotlin.String): kotlin.Boolean }) } +/** + * Removes a payment endpoint via the authenticated transport. + * + * # Parameters + * - `client`: Authenticated transport client + * - `method`: Payment method identifier to remove + * + * # Returns + * - `Ok(())` on successful removal + * - `Err` if the endpoint doesn't exist or transport fails + */ +@Throws(PaykitException::class, kotlin.coroutines.cancellation.CancellationException::class) +public suspend fun `removePaymentEndpoint`(`client`: PubkyAuthenticatedTransport, `method`: MethodId) { + return uniffiRustCallAsync( + UniffiLib.uniffi_bitkitcore_fn_func_remove_payment_endpoint( + FfiConverterTypePubkyAuthenticatedTransport.lower(`client`), + FfiConverterTypeMethodId.lower(`method`), + ), + { future, callback, continuation -> UniffiLib.ffi_bitkitcore_rust_future_poll_void(future, callback, continuation) }, + { future, continuation -> UniffiLib.ffi_bitkitcore_rust_future_complete_void(future, continuation) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_free_void(future) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_cancel_void(future) }, + // lift function + { Unit }, + + // Error FFI converter + PaykitExceptionErrorHandler, + ) +} + @Throws(ActivityException::class) public fun `removePreActivityMetadataTags`(`paymentId`: kotlin.String, `tags`: List) { uniffiRustCallWithError(ActivityExceptionErrorHandler) { uniffiRustCallStatus -> @@ -10756,6 +12285,74 @@ public fun `resetPreActivityMetadataTags`(`paymentId`: kotlin.String) { } } +/** + * Serializes session data into a token string suitable for deeplinks. + * + * # Security Considerations + * - The secret key should be encrypted before serialization + * - Use HTTPS/secure channels when transmitting + * - Consider adding expiration times + * - Implement token rotation for long-lived sessions + * + * # Example + * ``` + * let session_data = SessionData { + * public_key: "user_public_key".to_string(), + * secret_key: "encrypted_secret".to_string(), + * homeserver_url: Some("https://homeserver.example".to_string()), + * expires_at: Some(1234567890), + * metadata: None, + * }; + * + * let token = serialize_session_to_token(session_data)?; + * // token.token can now be passed through a deeplink + * ``` + */ +@Throws(PaykitException::class) +public fun `serializeSessionToToken`(`sessionData`: SessionData): SessionToken { + return FfiConverterTypeSessionToken.lift(uniffiRustCallWithError(PaykitExceptionErrorHandler) { uniffiRustCallStatus -> + UniffiLib.uniffi_bitkitcore_fn_func_serialize_session_to_token( + FfiConverterTypeSessionData.lower(`sessionData`), + uniffiRustCallStatus, + ) + }) +} + +/** + * Stores or updates a payment endpoint via the authenticated transport. + * + * # Parameters + * - `client`: Authenticated transport client + * - `method`: Payment method identifier (e.g., "lightning", "onchain") + * - `data`: Endpoint data payload (UTF-8 JSON or other text format) + * + * # Example + * ``` + * let method = MethodId { id: "lightning".to_string() }; + * let data = EndpointData { data: r#"{"bolt11":"lnbc..."}"#.to_string() }; + * set_payment_endpoint(&client, method, data).await?; + * ``` + */ +@Throws(PaykitException::class, kotlin.coroutines.cancellation.CancellationException::class) +public suspend fun `setPaymentEndpoint`(`client`: PubkyAuthenticatedTransport, `method`: MethodId, `data`: EndpointData) { + return uniffiRustCallAsync( + UniffiLib.uniffi_bitkitcore_fn_func_set_payment_endpoint( + FfiConverterTypePubkyAuthenticatedTransport.lower(`client`), + FfiConverterTypeMethodId.lower(`method`), + FfiConverterTypeEndpointData.lower(`data`), + ), + { future, callback, continuation -> UniffiLib.ffi_bitkitcore_rust_future_poll_void(future, callback, continuation) }, + { future, continuation -> UniffiLib.ffi_bitkitcore_rust_future_complete_void(future, continuation) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_free_void(future) }, + { future -> UniffiLib.ffi_bitkitcore_rust_future_cancel_void(future) }, + // lift function + { Unit }, + + // Error FFI converter + PaykitExceptionErrorHandler, + ) +} + @Throws(BlocktankException::class, kotlin.coroutines.cancellation.CancellationException::class) public suspend fun `testNotification`(`deviceToken`: kotlin.String, `secretMessage`: kotlin.String, `notificationType`: kotlin.String?, `customUrl`: kotlin.String?): kotlin.String { return uniffiRustCallAsync( @@ -11117,6 +12714,21 @@ public fun `validateMnemonic`(`mnemonicPhrase`: kotlin.String) { } } +/** + * Validates a deeplink URL without processing it. + * + * Use this to check if a URL is a valid Paykit deeplink before handling it. + */ +@Throws(PaykitException::class) +public fun `validatePaykitDeeplink`(`url`: kotlin.String): kotlin.Boolean { + return FfiConverterBoolean.lift(uniffiRustCallWithError(PaykitExceptionErrorHandler) { uniffiRustCallStatus -> + UniffiLib.uniffi_bitkitcore_fn_func_validate_paykit_deeplink( + FfiConverterString.lower(`url`), + uniffiRustCallStatus, + ) + }) +} + @Throws(ActivityException::class) public fun `wipeAllClosedChannels`() { uniffiRustCallWithError(ActivityExceptionErrorHandler) { uniffiRustCallStatus -> diff --git a/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.common.kt b/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.common.kt index b94b5bf..14f9d39 100644 --- a/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.common.kt +++ b/bindings/android/lib/src/main/kotlin/com/synonym/bitkitcore/bitkitcore.common.kt @@ -109,6 +109,96 @@ public object NoPointer + + +/** + * Authenticated transport wrapper for Paykit write operations. + */ +public interface PubkyAuthenticatedTransportInterface { + + /** + * Removes a payment endpoint. + * + * # Parameters + * - `method`: Payment method identifier to remove + * + * # Returns + * - `Ok(())` on successful removal + * - `Err` if the endpoint doesn't exist or transport fails + */ + @Throws(PaykitException::class, kotlin.coroutines.cancellation.CancellationException::class) + public suspend fun `removePaymentEndpoint`(`method`: MethodId) + + /** + * Stores or updates a payment endpoint. + * + * # Parameters + * - `method`: Payment method identifier (e.g., "lightning", "onchain") + * - `data`: Endpoint data payload (UTF-8 JSON or other text format) + */ + @Throws(PaykitException::class, kotlin.coroutines.cancellation.CancellationException::class) + public suspend fun `setPaymentEndpoint`(`method`: MethodId, `data`: EndpointData) + + public companion object +} + + + + +/** + * Unauthenticated transport wrapper for Paykit read operations. + */ +public interface PubkyUnauthenticatedTransportInterface { + + /** + * Returns known contacts (follows) of a given public key. + * + * # Parameters + * - `key`: Public key to query for contacts + * + * # Returns + * - `Ok(Vec)` with list of known contacts + * - Returns empty vector if no contacts are stored + * - `Err` only on transport failures + */ + @Throws(PaykitException::class, kotlin.coroutines.cancellation.CancellationException::class) + public suspend fun `getKnownContacts`(`key`: PublicKey): List + + /** + * Retrieves a specific payment endpoint for a payee and method. + * + * # Parameters + * - `payee`: Public key of the payee + * - `method`: Payment method identifier to query + * + * # Returns + * - `Ok(Some(EndpointData))` if the endpoint exists + * - `Ok(None)` if the endpoint is not published + * - `Err` only on transport failures + */ + @Throws(PaykitException::class, kotlin.coroutines.cancellation.CancellationException::class) + public suspend fun `getPaymentEndpoint`(`payee`: PublicKey, `method`: MethodId): EndpointData? + + /** + * Retrieves all supported payment methods for a given payee. + * + * # Parameters + * - `payee`: Public key of the payee to query + * + * # Returns + * - `Ok(SupportedPayments)` with map of method IDs to endpoint data + * - Returns empty map if no endpoints are published + * - `Err` only on transport failures + */ + @Throws(PaykitException::class, kotlin.coroutines.cancellation.CancellationException::class) + public suspend fun `getPaymentList`(`payee`: PublicKey): SupportedPayments + + public companion object +} + + + + /** * Account addresses */ @@ -439,6 +529,18 @@ public data class DeviceParams ( +/** + * Serialized payload served by a payment endpoint (UTF-8 text such as JSON, LNURL, etc.). + */ +@kotlinx.serialization.Serializable +public data class EndpointData ( + val `data`: kotlin.String +) { + public companion object +} + + + @kotlinx.serialization.Serializable public data class ErrorData ( val `errorDetails`: kotlin.String @@ -1182,6 +1284,18 @@ public data class MessageSignatureResponse ( +/** + * Identifier for a payment method specification (e.g., "lightning", "onchain", "bolt11"). + */ +@kotlinx.serialization.Serializable +public data class MethodId ( + val `id`: kotlin.String +) { + public companion object +} + + + /** * Multisig Redeem Script Type */ @@ -1252,6 +1366,29 @@ public data class OnchainActivity ( +/** + * Represents a parsed deeplink with Paykit session information + */ +@kotlinx.serialization.Serializable +public data class PaykitDeeplink ( + /** + * The action to perform (e.g., "session", "payment", "connect") + */ + val `action`: kotlin.String, + /** + * The session token if present + */ + val `sessionToken`: kotlin.String?, + /** + * Additional parameters from the deeplink + */ + val `parameters`: Map +) { + public companion object +} + + + /** * Payment request memo types */ @@ -1403,6 +1540,18 @@ public data class PubkyAuth ( +/** + * Public key wrapper for Paykit operations. + */ +@kotlinx.serialization.Serializable +public data class PublicKey ( + val `key`: kotlin.String +) { + public companion object +} + + + /** * Public key response containing the derived public key information */ @@ -1544,6 +1693,64 @@ public data class RefundMemo ( +@kotlinx.serialization.Serializable +public data class ScannedPaykitSession ( + val `url`: kotlin.String, + val `action`: kotlin.String, + val `token`: kotlin.String, + val `parameters`: Map +) { + public companion object +} + + + +/** + * Represents serializable session data that can be passed through a deeplink + */ +@kotlinx.serialization.Serializable +public data class SessionData ( + /** + * The user's public key + */ + val `publicKey`: kotlin.String, + /** + * The user's secret key (encrypted or encoded) + */ + val `secretKey`: kotlin.String, + /** + * Optional homeserver URL + */ + val `homeserverUrl`: kotlin.String?, + /** + * Session expiry timestamp (Unix timestamp) + */ + val `expiresAt`: kotlin.Long?, + /** + * Additional metadata + */ + val `metadata`: kotlin.String? +) { + public companion object +} + + + +/** + * Represents a session token that can be passed through deeplinks + */ +@kotlinx.serialization.Serializable +public data class SessionToken ( + /** + * Base64 URL-safe encoded session data + */ + val `token`: kotlin.String +) { + public companion object +} + + + /** * Signed transaction response */ @@ -1567,6 +1774,18 @@ public data class SignedTransactionResponse ( +/** + * Collection of supported payment entries keyed by method identifiers. + */ +@kotlinx.serialization.Serializable +public data class SupportedPayments ( + val `entries`: Map +) { + public companion object +} + + + /** * Text memo */ @@ -2645,6 +2864,59 @@ public enum class NetworkType { +/** + * Domain-specific error type for Paykit operations. + */ +public sealed class PaykitException: kotlin.Exception() { + + public class Unimplemented( + public val v1: kotlin.String, + ) : PaykitException() { + override val message: String + get() = "v1=${ v1 }" + } + + public class Transport( + public val v1: kotlin.String, + ) : PaykitException() { + override val message: String + get() = "v1=${ v1 }" + } + + public class InvalidPublicKey( + public val v1: kotlin.String, + ) : PaykitException() { + override val message: String + get() = "v1=${ v1 }" + } + + public class InvalidMethodId( + public val v1: kotlin.String, + ) : PaykitException() { + override val message: String + get() = "v1=${ v1 }" + } + + public class InvalidEndpointData( + public val v1: kotlin.String, + ) : PaykitException() { + override val message: String + get() = "v1=${ v1 }" + } + + public class SessionException( + public val v1: kotlin.String, + ) : PaykitException() { + override val message: String + get() = "v1=${ v1 }" + } + +} + + + + + @kotlinx.serialization.Serializable public enum class PaymentState { @@ -2691,6 +2963,11 @@ public sealed class Scanner { ) : Scanner() { } @kotlinx.serialization.Serializable + public data class PaykitSession( + val `data`: ScannedPaykitSession, + ) : Scanner() { + } + @kotlinx.serialization.Serializable public data class LnurlChannel( val `data`: LnurlChannelData, ) : Scanner() { @@ -3168,6 +3445,14 @@ public enum class WordCount { + + + + + + + + diff --git a/bindings/ios/BitkitCore.xcframework.zip b/bindings/ios/BitkitCore.xcframework.zip index 45a7918..c37b065 100644 Binary files a/bindings/ios/BitkitCore.xcframework.zip and b/bindings/ios/BitkitCore.xcframework.zip differ diff --git a/bindings/ios/BitkitCore.xcframework/Info.plist b/bindings/ios/BitkitCore.xcframework/Info.plist index 478a88f..b7357e0 100644 --- a/bindings/ios/BitkitCore.xcframework/Info.plist +++ b/bindings/ios/BitkitCore.xcframework/Info.plist @@ -10,7 +10,7 @@ HeadersPath Headers LibraryIdentifier - ios-arm64 + ios-arm64-simulator LibraryPath libbitkitcore.a SupportedArchitectures @@ -19,6 +19,8 @@ SupportedPlatform ios + SupportedPlatformVariant + simulator BinaryPath @@ -26,7 +28,7 @@ HeadersPath Headers LibraryIdentifier - ios-arm64-simulator + ios-arm64 LibraryPath libbitkitcore.a SupportedArchitectures @@ -35,8 +37,6 @@ SupportedPlatform ios - SupportedPlatformVariant - simulator CFBundlePackageType diff --git a/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/Headers/bitkitcoreFFI.h b/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/Headers/bitkitcoreFFI.h index 4562536..9c1c486 100644 --- a/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/Headers/bitkitcoreFFI.h +++ b/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/Headers/bitkitcoreFFI.h @@ -250,6 +250,63 @@ typedef struct UniffiForeignFutureStructVoid { typedef void (*UniffiForeignFutureCompleteVoid)(uint64_t, UniffiForeignFutureStructVoid ); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_PUBKYAUTHENTICATEDTRANSPORT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_PUBKYAUTHENTICATEDTRANSPORT +void*_Nonnull uniffi_bitkitcore_fn_clone_pubkyauthenticatedtransport(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FREE_PUBKYAUTHENTICATEDTRANSPORT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FREE_PUBKYAUTHENTICATEDTRANSPORT +void uniffi_bitkitcore_fn_free_pubkyauthenticatedtransport(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CONSTRUCTOR_PUBKYAUTHENTICATEDTRANSPORT_NEW +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CONSTRUCTOR_PUBKYAUTHENTICATEDTRANSPORT_NEW +void*_Nonnull uniffi_bitkitcore_fn_constructor_pubkyauthenticatedtransport_new(RustCallStatus *_Nonnull out_status + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYAUTHENTICATEDTRANSPORT_REMOVE_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYAUTHENTICATEDTRANSPORT_REMOVE_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_remove_payment_endpoint(void*_Nonnull ptr, RustBuffer method +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYAUTHENTICATEDTRANSPORT_SET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYAUTHENTICATEDTRANSPORT_SET_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_set_payment_endpoint(void*_Nonnull ptr, RustBuffer method, RustBuffer data +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_PUBKYUNAUTHENTICATEDTRANSPORT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_PUBKYUNAUTHENTICATEDTRANSPORT +void*_Nonnull uniffi_bitkitcore_fn_clone_pubkyunauthenticatedtransport(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FREE_PUBKYUNAUTHENTICATEDTRANSPORT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FREE_PUBKYUNAUTHENTICATEDTRANSPORT +void uniffi_bitkitcore_fn_free_pubkyunauthenticatedtransport(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CONSTRUCTOR_PUBKYUNAUTHENTICATEDTRANSPORT_NEW +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CONSTRUCTOR_PUBKYUNAUTHENTICATEDTRANSPORT_NEW +void*_Nonnull uniffi_bitkitcore_fn_constructor_pubkyunauthenticatedtransport_new(RustCallStatus *_Nonnull out_status + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_KNOWN_CONTACTS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_KNOWN_CONTACTS +uint64_t uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_known_contacts(void*_Nonnull ptr, RustBuffer key +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_endpoint(void*_Nonnull ptr, RustBuffer payee, RustBuffer method +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_LIST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_LIST +uint64_t uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_list(void*_Nonnull ptr, RustBuffer payee +); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_ACTIVITY_WIPE_ALL #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_ACTIVITY_WIPE_ALL @@ -305,11 +362,26 @@ RustBuffer uniffi_bitkitcore_fn_func_create_channel_request_url(RustBuffer k1, R uint64_t uniffi_bitkitcore_fn_func_create_cjit_entry(uint64_t channel_size_sat, uint64_t invoice_sat, RustBuffer invoice_description, RustBuffer node_id, uint32_t channel_expiry_weeks, RustBuffer options ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_DEEPLINK_FROM_TOKEN +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_DEEPLINK_FROM_TOKEN +RustBuffer uniffi_bitkitcore_fn_func_create_deeplink_from_token(RustBuffer base_url, RustBuffer action, RustBuffer token, RustBuffer additional_params, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_ORDER #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_ORDER uint64_t uniffi_bitkitcore_fn_func_create_order(uint64_t lsp_balance_sat, uint32_t channel_expiry_weeks, RustBuffer options ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_PUBKY_RING_SESSION_REQUEST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_PUBKY_RING_SESSION_REQUEST +RustBuffer uniffi_bitkitcore_fn_func_create_pubky_ring_session_request(RustBuffer callback_url, RustBuffer additional_params, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_SESSION_TOKEN_FROM_KEYPAIR +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_SESSION_TOKEN_FROM_KEYPAIR +RustBuffer uniffi_bitkitcore_fn_func_create_session_token_from_keypair(RustBuffer public_key, RustBuffer secret_key, RustBuffer homeserver_url, RustBuffer expires_in_seconds, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_WITHDRAW_CALLBACK_URL #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_WITHDRAW_CALLBACK_URL RustBuffer uniffi_bitkitcore_fn_func_create_withdraw_callback_url(RustBuffer k1, RustBuffer callback, RustBuffer payment_request, RustCallStatus *_Nonnull out_status @@ -345,6 +417,11 @@ RustBuffer uniffi_bitkitcore_fn_func_derive_bitcoin_addresses(RustBuffer mnemoni RustBuffer uniffi_bitkitcore_fn_func_derive_private_key(RustBuffer mnemonic_phrase, RustBuffer derivation_path_str, RustBuffer network, RustBuffer bip39_passphrase, RustCallStatus *_Nonnull out_status ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_DESERIALIZE_TOKEN_TO_SESSION +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_DESERIALIZE_TOKEN_TO_SESSION +RustBuffer uniffi_bitkitcore_fn_func_deserialize_token_to_session(RustBuffer token, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_ENTROPY_TO_MNEMONIC #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_ENTROPY_TO_MNEMONIC RustBuffer uniffi_bitkitcore_fn_func_entropy_to_mnemonic(RustBuffer entropy, RustCallStatus *_Nonnull out_status @@ -444,6 +521,11 @@ uint64_t uniffi_bitkitcore_fn_func_get_gift(RustBuffer gift_id uint64_t uniffi_bitkitcore_fn_func_get_info(RustBuffer refresh ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_KNOWN_CONTACTS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_KNOWN_CONTACTS +uint64_t uniffi_bitkitcore_fn_func_get_known_contacts(void*_Nonnull reader, RustBuffer key +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_LNURL_INVOICE #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_LNURL_INVOICE uint64_t uniffi_bitkitcore_fn_func_get_lnurl_invoice(RustBuffer address, uint64_t amount_satoshis @@ -464,6 +546,16 @@ uint64_t uniffi_bitkitcore_fn_func_get_orders(RustBuffer order_ids, RustBuffer f uint64_t uniffi_bitkitcore_fn_func_get_payment(RustBuffer payment_id ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_func_get_payment_endpoint(void*_Nonnull reader, RustBuffer payee, RustBuffer method +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PAYMENT_LIST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PAYMENT_LIST +uint64_t uniffi_bitkitcore_fn_func_get_payment_list(void*_Nonnull reader, RustBuffer payee +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PRE_ACTIVITY_METADATA #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PRE_ACTIVITY_METADATA RustBuffer uniffi_bitkitcore_fn_func_get_pre_activity_metadata(RustBuffer search_key, int8_t search_by_address, RustCallStatus *_Nonnull out_status @@ -524,6 +616,11 @@ RustBuffer uniffi_bitkitcore_fn_func_mnemonic_to_seed(RustBuffer mnemonic_phrase uint64_t uniffi_bitkitcore_fn_func_open_channel(RustBuffer order_id, RustBuffer connection_string ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_PARSE_PAYKIT_DEEPLINK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_PARSE_PAYKIT_DEEPLINK +RustBuffer uniffi_bitkitcore_fn_func_parse_paykit_deeplink(RustBuffer url, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REFRESH_ACTIVE_CJIT_ENTRIES #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REFRESH_ACTIVE_CJIT_ENTRIES uint64_t uniffi_bitkitcore_fn_func_refresh_active_cjit_entries(void @@ -571,6 +668,11 @@ uint64_t uniffi_bitkitcore_fn_func_regtest_pay(RustBuffer invoice, RustBuffer am int8_t uniffi_bitkitcore_fn_func_remove_closed_channel_by_id(RustBuffer channel_id, RustCallStatus *_Nonnull out_status ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REMOVE_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REMOVE_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_func_remove_payment_endpoint(void*_Nonnull client, RustBuffer method +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REMOVE_PRE_ACTIVITY_METADATA_TAGS #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REMOVE_PRE_ACTIVITY_METADATA_TAGS void uniffi_bitkitcore_fn_func_remove_pre_activity_metadata_tags(RustBuffer payment_id, RustBuffer tags, RustCallStatus *_Nonnull out_status @@ -586,6 +688,16 @@ void uniffi_bitkitcore_fn_func_remove_tags(RustBuffer activity_id, RustBuffer ta void uniffi_bitkitcore_fn_func_reset_pre_activity_metadata_tags(RustBuffer payment_id, RustCallStatus *_Nonnull out_status ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_SERIALIZE_SESSION_TO_TOKEN +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_SERIALIZE_SESSION_TO_TOKEN +RustBuffer uniffi_bitkitcore_fn_func_serialize_session_to_token(RustBuffer session_data, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_SET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_SET_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_func_set_payment_endpoint(void*_Nonnull client, RustBuffer method, RustBuffer data +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_TEST_NOTIFICATION #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_TEST_NOTIFICATION uint64_t uniffi_bitkitcore_fn_func_test_notification(RustBuffer device_token, RustBuffer secret_message, RustBuffer notification_type, RustBuffer custom_url @@ -706,6 +818,11 @@ RustBuffer uniffi_bitkitcore_fn_func_validate_bitcoin_address(RustBuffer address void uniffi_bitkitcore_fn_func_validate_mnemonic(RustBuffer mnemonic_phrase, RustCallStatus *_Nonnull out_status ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_VALIDATE_PAYKIT_DEEPLINK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_VALIDATE_PAYKIT_DEEPLINK +int8_t uniffi_bitkitcore_fn_func_validate_paykit_deeplink(RustBuffer url, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_WIPE_ALL_CLOSED_CHANNELS #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_WIPE_ALL_CLOSED_CHANNELS void uniffi_bitkitcore_fn_func_wipe_all_closed_channels(RustCallStatus *_Nonnull out_status @@ -1056,12 +1173,30 @@ uint16_t uniffi_bitkitcore_checksum_func_create_channel_request_url(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_CJIT_ENTRY uint16_t uniffi_bitkitcore_checksum_func_create_cjit_entry(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_DEEPLINK_FROM_TOKEN +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_DEEPLINK_FROM_TOKEN +uint16_t uniffi_bitkitcore_checksum_func_create_deeplink_from_token(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_ORDER #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_ORDER uint16_t uniffi_bitkitcore_checksum_func_create_order(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_PUBKY_RING_SESSION_REQUEST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_PUBKY_RING_SESSION_REQUEST +uint16_t uniffi_bitkitcore_checksum_func_create_pubky_ring_session_request(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_SESSION_TOKEN_FROM_KEYPAIR +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_SESSION_TOKEN_FROM_KEYPAIR +uint16_t uniffi_bitkitcore_checksum_func_create_session_token_from_keypair(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_WITHDRAW_CALLBACK_URL @@ -1104,6 +1239,12 @@ uint16_t uniffi_bitkitcore_checksum_func_derive_bitcoin_addresses(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_DERIVE_PRIVATE_KEY uint16_t uniffi_bitkitcore_checksum_func_derive_private_key(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_DESERIALIZE_TOKEN_TO_SESSION +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_DESERIALIZE_TOKEN_TO_SESSION +uint16_t uniffi_bitkitcore_checksum_func_deserialize_token_to_session(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_ENTROPY_TO_MNEMONIC @@ -1218,6 +1359,12 @@ uint16_t uniffi_bitkitcore_checksum_func_get_gift(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_INFO uint16_t uniffi_bitkitcore_checksum_func_get_info(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_KNOWN_CONTACTS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_KNOWN_CONTACTS +uint16_t uniffi_bitkitcore_checksum_func_get_known_contacts(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_LNURL_INVOICE @@ -1242,6 +1389,18 @@ uint16_t uniffi_bitkitcore_checksum_func_get_orders(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PAYMENT uint16_t uniffi_bitkitcore_checksum_func_get_payment(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_func_get_payment_endpoint(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PAYMENT_LIST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PAYMENT_LIST +uint16_t uniffi_bitkitcore_checksum_func_get_payment_list(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PRE_ACTIVITY_METADATA @@ -1314,6 +1473,12 @@ uint16_t uniffi_bitkitcore_checksum_func_mnemonic_to_seed(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_OPEN_CHANNEL uint16_t uniffi_bitkitcore_checksum_func_open_channel(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_PARSE_PAYKIT_DEEPLINK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_PARSE_PAYKIT_DEEPLINK +uint16_t uniffi_bitkitcore_checksum_func_parse_paykit_deeplink(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REFRESH_ACTIVE_CJIT_ENTRIES @@ -1368,6 +1533,12 @@ uint16_t uniffi_bitkitcore_checksum_func_regtest_pay(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REMOVE_CLOSED_CHANNEL_BY_ID uint16_t uniffi_bitkitcore_checksum_func_remove_closed_channel_by_id(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REMOVE_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REMOVE_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_func_remove_payment_endpoint(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REMOVE_PRE_ACTIVITY_METADATA_TAGS @@ -1386,6 +1557,18 @@ uint16_t uniffi_bitkitcore_checksum_func_remove_tags(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_RESET_PRE_ACTIVITY_METADATA_TAGS uint16_t uniffi_bitkitcore_checksum_func_reset_pre_activity_metadata_tags(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_SERIALIZE_SESSION_TO_TOKEN +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_SERIALIZE_SESSION_TO_TOKEN +uint16_t uniffi_bitkitcore_checksum_func_serialize_session_to_token(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_SET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_SET_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_func_set_payment_endpoint(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_TEST_NOTIFICATION @@ -1530,6 +1713,12 @@ uint16_t uniffi_bitkitcore_checksum_func_validate_bitcoin_address(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_VALIDATE_MNEMONIC uint16_t uniffi_bitkitcore_checksum_func_validate_mnemonic(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_VALIDATE_PAYKIT_DEEPLINK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_VALIDATE_PAYKIT_DEEPLINK +uint16_t uniffi_bitkitcore_checksum_func_validate_paykit_deeplink(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_WIPE_ALL_CLOSED_CHANNELS @@ -1542,6 +1731,48 @@ uint16_t uniffi_bitkitcore_checksum_func_wipe_all_closed_channels(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_WIPE_ALL_DATABASES uint16_t uniffi_bitkitcore_checksum_func_wipe_all_databases(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYAUTHENTICATEDTRANSPORT_REMOVE_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYAUTHENTICATEDTRANSPORT_REMOVE_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_remove_payment_endpoint(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYAUTHENTICATEDTRANSPORT_SET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYAUTHENTICATEDTRANSPORT_SET_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_set_payment_endpoint(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_KNOWN_CONTACTS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_KNOWN_CONTACTS +uint16_t uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_known_contacts(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_endpoint(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_LIST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_LIST +uint16_t uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_list(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_CONSTRUCTOR_PUBKYAUTHENTICATEDTRANSPORT_NEW +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_CONSTRUCTOR_PUBKYAUTHENTICATEDTRANSPORT_NEW +uint16_t uniffi_bitkitcore_checksum_constructor_pubkyauthenticatedtransport_new(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_CONSTRUCTOR_PUBKYUNAUTHENTICATEDTRANSPORT_NEW +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_CONSTRUCTOR_PUBKYUNAUTHENTICATEDTRANSPORT_NEW +uint16_t uniffi_bitkitcore_checksum_constructor_pubkyunauthenticatedtransport_new(void + ); #endif #ifndef UNIFFI_FFIDEF_FFI_BITKITCORE_UNIFFI_CONTRACT_VERSION diff --git a/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/libbitkitcore.a b/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/libbitkitcore.a index 4c96b3a..2f75b73 100644 Binary files a/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/libbitkitcore.a and b/bindings/ios/BitkitCore.xcframework/ios-arm64-simulator/libbitkitcore.a differ diff --git a/bindings/ios/BitkitCore.xcframework/ios-arm64/Headers/bitkitcoreFFI.h b/bindings/ios/BitkitCore.xcframework/ios-arm64/Headers/bitkitcoreFFI.h index 4562536..9c1c486 100644 --- a/bindings/ios/BitkitCore.xcframework/ios-arm64/Headers/bitkitcoreFFI.h +++ b/bindings/ios/BitkitCore.xcframework/ios-arm64/Headers/bitkitcoreFFI.h @@ -250,6 +250,63 @@ typedef struct UniffiForeignFutureStructVoid { typedef void (*UniffiForeignFutureCompleteVoid)(uint64_t, UniffiForeignFutureStructVoid ); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_PUBKYAUTHENTICATEDTRANSPORT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_PUBKYAUTHENTICATEDTRANSPORT +void*_Nonnull uniffi_bitkitcore_fn_clone_pubkyauthenticatedtransport(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FREE_PUBKYAUTHENTICATEDTRANSPORT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FREE_PUBKYAUTHENTICATEDTRANSPORT +void uniffi_bitkitcore_fn_free_pubkyauthenticatedtransport(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CONSTRUCTOR_PUBKYAUTHENTICATEDTRANSPORT_NEW +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CONSTRUCTOR_PUBKYAUTHENTICATEDTRANSPORT_NEW +void*_Nonnull uniffi_bitkitcore_fn_constructor_pubkyauthenticatedtransport_new(RustCallStatus *_Nonnull out_status + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYAUTHENTICATEDTRANSPORT_REMOVE_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYAUTHENTICATEDTRANSPORT_REMOVE_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_remove_payment_endpoint(void*_Nonnull ptr, RustBuffer method +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYAUTHENTICATEDTRANSPORT_SET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYAUTHENTICATEDTRANSPORT_SET_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_set_payment_endpoint(void*_Nonnull ptr, RustBuffer method, RustBuffer data +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_PUBKYUNAUTHENTICATEDTRANSPORT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_PUBKYUNAUTHENTICATEDTRANSPORT +void*_Nonnull uniffi_bitkitcore_fn_clone_pubkyunauthenticatedtransport(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FREE_PUBKYUNAUTHENTICATEDTRANSPORT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FREE_PUBKYUNAUTHENTICATEDTRANSPORT +void uniffi_bitkitcore_fn_free_pubkyunauthenticatedtransport(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CONSTRUCTOR_PUBKYUNAUTHENTICATEDTRANSPORT_NEW +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CONSTRUCTOR_PUBKYUNAUTHENTICATEDTRANSPORT_NEW +void*_Nonnull uniffi_bitkitcore_fn_constructor_pubkyunauthenticatedtransport_new(RustCallStatus *_Nonnull out_status + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_KNOWN_CONTACTS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_KNOWN_CONTACTS +uint64_t uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_known_contacts(void*_Nonnull ptr, RustBuffer key +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_endpoint(void*_Nonnull ptr, RustBuffer payee, RustBuffer method +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_LIST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_LIST +uint64_t uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_list(void*_Nonnull ptr, RustBuffer payee +); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_ACTIVITY_WIPE_ALL #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_ACTIVITY_WIPE_ALL @@ -305,11 +362,26 @@ RustBuffer uniffi_bitkitcore_fn_func_create_channel_request_url(RustBuffer k1, R uint64_t uniffi_bitkitcore_fn_func_create_cjit_entry(uint64_t channel_size_sat, uint64_t invoice_sat, RustBuffer invoice_description, RustBuffer node_id, uint32_t channel_expiry_weeks, RustBuffer options ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_DEEPLINK_FROM_TOKEN +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_DEEPLINK_FROM_TOKEN +RustBuffer uniffi_bitkitcore_fn_func_create_deeplink_from_token(RustBuffer base_url, RustBuffer action, RustBuffer token, RustBuffer additional_params, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_ORDER #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_ORDER uint64_t uniffi_bitkitcore_fn_func_create_order(uint64_t lsp_balance_sat, uint32_t channel_expiry_weeks, RustBuffer options ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_PUBKY_RING_SESSION_REQUEST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_PUBKY_RING_SESSION_REQUEST +RustBuffer uniffi_bitkitcore_fn_func_create_pubky_ring_session_request(RustBuffer callback_url, RustBuffer additional_params, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_SESSION_TOKEN_FROM_KEYPAIR +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_SESSION_TOKEN_FROM_KEYPAIR +RustBuffer uniffi_bitkitcore_fn_func_create_session_token_from_keypair(RustBuffer public_key, RustBuffer secret_key, RustBuffer homeserver_url, RustBuffer expires_in_seconds, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_WITHDRAW_CALLBACK_URL #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_WITHDRAW_CALLBACK_URL RustBuffer uniffi_bitkitcore_fn_func_create_withdraw_callback_url(RustBuffer k1, RustBuffer callback, RustBuffer payment_request, RustCallStatus *_Nonnull out_status @@ -345,6 +417,11 @@ RustBuffer uniffi_bitkitcore_fn_func_derive_bitcoin_addresses(RustBuffer mnemoni RustBuffer uniffi_bitkitcore_fn_func_derive_private_key(RustBuffer mnemonic_phrase, RustBuffer derivation_path_str, RustBuffer network, RustBuffer bip39_passphrase, RustCallStatus *_Nonnull out_status ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_DESERIALIZE_TOKEN_TO_SESSION +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_DESERIALIZE_TOKEN_TO_SESSION +RustBuffer uniffi_bitkitcore_fn_func_deserialize_token_to_session(RustBuffer token, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_ENTROPY_TO_MNEMONIC #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_ENTROPY_TO_MNEMONIC RustBuffer uniffi_bitkitcore_fn_func_entropy_to_mnemonic(RustBuffer entropy, RustCallStatus *_Nonnull out_status @@ -444,6 +521,11 @@ uint64_t uniffi_bitkitcore_fn_func_get_gift(RustBuffer gift_id uint64_t uniffi_bitkitcore_fn_func_get_info(RustBuffer refresh ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_KNOWN_CONTACTS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_KNOWN_CONTACTS +uint64_t uniffi_bitkitcore_fn_func_get_known_contacts(void*_Nonnull reader, RustBuffer key +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_LNURL_INVOICE #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_LNURL_INVOICE uint64_t uniffi_bitkitcore_fn_func_get_lnurl_invoice(RustBuffer address, uint64_t amount_satoshis @@ -464,6 +546,16 @@ uint64_t uniffi_bitkitcore_fn_func_get_orders(RustBuffer order_ids, RustBuffer f uint64_t uniffi_bitkitcore_fn_func_get_payment(RustBuffer payment_id ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_func_get_payment_endpoint(void*_Nonnull reader, RustBuffer payee, RustBuffer method +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PAYMENT_LIST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PAYMENT_LIST +uint64_t uniffi_bitkitcore_fn_func_get_payment_list(void*_Nonnull reader, RustBuffer payee +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PRE_ACTIVITY_METADATA #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PRE_ACTIVITY_METADATA RustBuffer uniffi_bitkitcore_fn_func_get_pre_activity_metadata(RustBuffer search_key, int8_t search_by_address, RustCallStatus *_Nonnull out_status @@ -524,6 +616,11 @@ RustBuffer uniffi_bitkitcore_fn_func_mnemonic_to_seed(RustBuffer mnemonic_phrase uint64_t uniffi_bitkitcore_fn_func_open_channel(RustBuffer order_id, RustBuffer connection_string ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_PARSE_PAYKIT_DEEPLINK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_PARSE_PAYKIT_DEEPLINK +RustBuffer uniffi_bitkitcore_fn_func_parse_paykit_deeplink(RustBuffer url, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REFRESH_ACTIVE_CJIT_ENTRIES #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REFRESH_ACTIVE_CJIT_ENTRIES uint64_t uniffi_bitkitcore_fn_func_refresh_active_cjit_entries(void @@ -571,6 +668,11 @@ uint64_t uniffi_bitkitcore_fn_func_regtest_pay(RustBuffer invoice, RustBuffer am int8_t uniffi_bitkitcore_fn_func_remove_closed_channel_by_id(RustBuffer channel_id, RustCallStatus *_Nonnull out_status ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REMOVE_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REMOVE_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_func_remove_payment_endpoint(void*_Nonnull client, RustBuffer method +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REMOVE_PRE_ACTIVITY_METADATA_TAGS #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REMOVE_PRE_ACTIVITY_METADATA_TAGS void uniffi_bitkitcore_fn_func_remove_pre_activity_metadata_tags(RustBuffer payment_id, RustBuffer tags, RustCallStatus *_Nonnull out_status @@ -586,6 +688,16 @@ void uniffi_bitkitcore_fn_func_remove_tags(RustBuffer activity_id, RustBuffer ta void uniffi_bitkitcore_fn_func_reset_pre_activity_metadata_tags(RustBuffer payment_id, RustCallStatus *_Nonnull out_status ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_SERIALIZE_SESSION_TO_TOKEN +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_SERIALIZE_SESSION_TO_TOKEN +RustBuffer uniffi_bitkitcore_fn_func_serialize_session_to_token(RustBuffer session_data, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_SET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_SET_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_func_set_payment_endpoint(void*_Nonnull client, RustBuffer method, RustBuffer data +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_TEST_NOTIFICATION #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_TEST_NOTIFICATION uint64_t uniffi_bitkitcore_fn_func_test_notification(RustBuffer device_token, RustBuffer secret_message, RustBuffer notification_type, RustBuffer custom_url @@ -706,6 +818,11 @@ RustBuffer uniffi_bitkitcore_fn_func_validate_bitcoin_address(RustBuffer address void uniffi_bitkitcore_fn_func_validate_mnemonic(RustBuffer mnemonic_phrase, RustCallStatus *_Nonnull out_status ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_VALIDATE_PAYKIT_DEEPLINK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_VALIDATE_PAYKIT_DEEPLINK +int8_t uniffi_bitkitcore_fn_func_validate_paykit_deeplink(RustBuffer url, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_WIPE_ALL_CLOSED_CHANNELS #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_WIPE_ALL_CLOSED_CHANNELS void uniffi_bitkitcore_fn_func_wipe_all_closed_channels(RustCallStatus *_Nonnull out_status @@ -1056,12 +1173,30 @@ uint16_t uniffi_bitkitcore_checksum_func_create_channel_request_url(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_CJIT_ENTRY uint16_t uniffi_bitkitcore_checksum_func_create_cjit_entry(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_DEEPLINK_FROM_TOKEN +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_DEEPLINK_FROM_TOKEN +uint16_t uniffi_bitkitcore_checksum_func_create_deeplink_from_token(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_ORDER #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_ORDER uint16_t uniffi_bitkitcore_checksum_func_create_order(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_PUBKY_RING_SESSION_REQUEST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_PUBKY_RING_SESSION_REQUEST +uint16_t uniffi_bitkitcore_checksum_func_create_pubky_ring_session_request(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_SESSION_TOKEN_FROM_KEYPAIR +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_SESSION_TOKEN_FROM_KEYPAIR +uint16_t uniffi_bitkitcore_checksum_func_create_session_token_from_keypair(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_WITHDRAW_CALLBACK_URL @@ -1104,6 +1239,12 @@ uint16_t uniffi_bitkitcore_checksum_func_derive_bitcoin_addresses(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_DERIVE_PRIVATE_KEY uint16_t uniffi_bitkitcore_checksum_func_derive_private_key(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_DESERIALIZE_TOKEN_TO_SESSION +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_DESERIALIZE_TOKEN_TO_SESSION +uint16_t uniffi_bitkitcore_checksum_func_deserialize_token_to_session(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_ENTROPY_TO_MNEMONIC @@ -1218,6 +1359,12 @@ uint16_t uniffi_bitkitcore_checksum_func_get_gift(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_INFO uint16_t uniffi_bitkitcore_checksum_func_get_info(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_KNOWN_CONTACTS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_KNOWN_CONTACTS +uint16_t uniffi_bitkitcore_checksum_func_get_known_contacts(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_LNURL_INVOICE @@ -1242,6 +1389,18 @@ uint16_t uniffi_bitkitcore_checksum_func_get_orders(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PAYMENT uint16_t uniffi_bitkitcore_checksum_func_get_payment(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_func_get_payment_endpoint(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PAYMENT_LIST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PAYMENT_LIST +uint16_t uniffi_bitkitcore_checksum_func_get_payment_list(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PRE_ACTIVITY_METADATA @@ -1314,6 +1473,12 @@ uint16_t uniffi_bitkitcore_checksum_func_mnemonic_to_seed(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_OPEN_CHANNEL uint16_t uniffi_bitkitcore_checksum_func_open_channel(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_PARSE_PAYKIT_DEEPLINK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_PARSE_PAYKIT_DEEPLINK +uint16_t uniffi_bitkitcore_checksum_func_parse_paykit_deeplink(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REFRESH_ACTIVE_CJIT_ENTRIES @@ -1368,6 +1533,12 @@ uint16_t uniffi_bitkitcore_checksum_func_regtest_pay(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REMOVE_CLOSED_CHANNEL_BY_ID uint16_t uniffi_bitkitcore_checksum_func_remove_closed_channel_by_id(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REMOVE_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REMOVE_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_func_remove_payment_endpoint(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REMOVE_PRE_ACTIVITY_METADATA_TAGS @@ -1386,6 +1557,18 @@ uint16_t uniffi_bitkitcore_checksum_func_remove_tags(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_RESET_PRE_ACTIVITY_METADATA_TAGS uint16_t uniffi_bitkitcore_checksum_func_reset_pre_activity_metadata_tags(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_SERIALIZE_SESSION_TO_TOKEN +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_SERIALIZE_SESSION_TO_TOKEN +uint16_t uniffi_bitkitcore_checksum_func_serialize_session_to_token(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_SET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_SET_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_func_set_payment_endpoint(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_TEST_NOTIFICATION @@ -1530,6 +1713,12 @@ uint16_t uniffi_bitkitcore_checksum_func_validate_bitcoin_address(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_VALIDATE_MNEMONIC uint16_t uniffi_bitkitcore_checksum_func_validate_mnemonic(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_VALIDATE_PAYKIT_DEEPLINK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_VALIDATE_PAYKIT_DEEPLINK +uint16_t uniffi_bitkitcore_checksum_func_validate_paykit_deeplink(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_WIPE_ALL_CLOSED_CHANNELS @@ -1542,6 +1731,48 @@ uint16_t uniffi_bitkitcore_checksum_func_wipe_all_closed_channels(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_WIPE_ALL_DATABASES uint16_t uniffi_bitkitcore_checksum_func_wipe_all_databases(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYAUTHENTICATEDTRANSPORT_REMOVE_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYAUTHENTICATEDTRANSPORT_REMOVE_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_remove_payment_endpoint(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYAUTHENTICATEDTRANSPORT_SET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYAUTHENTICATEDTRANSPORT_SET_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_set_payment_endpoint(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_KNOWN_CONTACTS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_KNOWN_CONTACTS +uint16_t uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_known_contacts(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_endpoint(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_LIST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_LIST +uint16_t uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_list(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_CONSTRUCTOR_PUBKYAUTHENTICATEDTRANSPORT_NEW +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_CONSTRUCTOR_PUBKYAUTHENTICATEDTRANSPORT_NEW +uint16_t uniffi_bitkitcore_checksum_constructor_pubkyauthenticatedtransport_new(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_CONSTRUCTOR_PUBKYUNAUTHENTICATEDTRANSPORT_NEW +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_CONSTRUCTOR_PUBKYUNAUTHENTICATEDTRANSPORT_NEW +uint16_t uniffi_bitkitcore_checksum_constructor_pubkyunauthenticatedtransport_new(void + ); #endif #ifndef UNIFFI_FFIDEF_FFI_BITKITCORE_UNIFFI_CONTRACT_VERSION diff --git a/bindings/ios/BitkitCore.xcframework/ios-arm64/libbitkitcore.a b/bindings/ios/BitkitCore.xcframework/ios-arm64/libbitkitcore.a index 23e3338..f04b1a0 100644 Binary files a/bindings/ios/BitkitCore.xcframework/ios-arm64/libbitkitcore.a and b/bindings/ios/BitkitCore.xcframework/ios-arm64/libbitkitcore.a differ diff --git a/bindings/ios/bitkitcore.swift b/bindings/ios/bitkitcore.swift index 6f8675f..1a16d9c 100644 --- a/bindings/ios/bitkitcore.swift +++ b/bindings/ios/bitkitcore.swift @@ -445,6 +445,22 @@ fileprivate struct FfiConverterUInt64: FfiConverterPrimitive { } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterInt64: FfiConverterPrimitive { + typealias FfiType = Int64 + typealias SwiftType = Int64 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Int64 { + return try lift(readInt(&buf)) + } + + public static func write(_ value: Int64, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -545,6 +561,464 @@ fileprivate struct FfiConverterData: FfiConverterRustBuffer { } + + +/** + * Authenticated transport wrapper for Paykit write operations. + */ +public protocol PubkyAuthenticatedTransportProtocol: AnyObject, Sendable { + + /** + * Removes a payment endpoint. + * + * # Parameters + * - `method`: Payment method identifier to remove + * + * # Returns + * - `Ok(())` on successful removal + * - `Err` if the endpoint doesn't exist or transport fails + */ + func removePaymentEndpoint(method: MethodId) async throws + + /** + * Stores or updates a payment endpoint. + * + * # Parameters + * - `method`: Payment method identifier (e.g., "lightning", "onchain") + * - `data`: Endpoint data payload (UTF-8 JSON or other text format) + */ + func setPaymentEndpoint(method: MethodId, data: EndpointData) async throws + +} +/** + * Authenticated transport wrapper for Paykit write operations. + */ +open class PubkyAuthenticatedTransport: PubkyAuthenticatedTransportProtocol, @unchecked Sendable { + fileprivate let pointer: UnsafeMutableRawPointer! + + /// Used to instantiate a [FFIObject] without an actual pointer, for fakes in tests, mostly. +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public struct NoPointer { + public init() {} + } + + // TODO: We'd like this to be `private` but for Swifty reasons, + // we can't implement `FfiConverter` without making this `required` and we can't + // make it `required` without making it `public`. +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + required public init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) { + self.pointer = pointer + } + + // This constructor can be used to instantiate a fake object. + // - Parameter noPointer: Placeholder value so we can have a constructor separate from the default empty one that may be implemented for classes extending [FFIObject]. + // + // - Warning: + // Any object instantiated with this constructor cannot be passed to an actual Rust-backed object. Since there isn't a backing [Pointer] the FFI lower functions will crash. +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public init(noPointer: NoPointer) { + self.pointer = nil + } + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public func uniffiClonePointer() -> UnsafeMutableRawPointer { + return try! rustCall { uniffi_bitkitcore_fn_clone_pubkyauthenticatedtransport(self.pointer, $0) } + } + /** + * Creates a new authenticated transport. + * Note: This requires proper session initialization which should be handled + * by the application layer. For now, this returns an error indicating the + * need for external session management. + */ +public convenience init()throws { + let pointer = + try rustCallWithError(FfiConverterTypePaykitError_lift) { + uniffi_bitkitcore_fn_constructor_pubkyauthenticatedtransport_new($0 + ) +} + self.init(unsafeFromRawPointer: pointer) +} + + deinit { + guard let pointer = pointer else { + return + } + + try! rustCall { uniffi_bitkitcore_fn_free_pubkyauthenticatedtransport(pointer, $0) } + } + + + + + /** + * Removes a payment endpoint. + * + * # Parameters + * - `method`: Payment method identifier to remove + * + * # Returns + * - `Ok(())` on successful removal + * - `Err` if the endpoint doesn't exist or transport fails + */ +open func removePaymentEndpoint(method: MethodId)async throws { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_remove_payment_endpoint( + self.uniffiClonePointer(), + FfiConverterTypeMethodId_lower(method) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_void, + completeFunc: ffi_bitkitcore_rust_future_complete_void, + freeFunc: ffi_bitkitcore_rust_future_free_void, + liftFunc: { $0 }, + errorHandler: FfiConverterTypePaykitError_lift + ) +} + + /** + * Stores or updates a payment endpoint. + * + * # Parameters + * - `method`: Payment method identifier (e.g., "lightning", "onchain") + * - `data`: Endpoint data payload (UTF-8 JSON or other text format) + */ +open func setPaymentEndpoint(method: MethodId, data: EndpointData)async throws { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_set_payment_endpoint( + self.uniffiClonePointer(), + FfiConverterTypeMethodId_lower(method),FfiConverterTypeEndpointData_lower(data) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_void, + completeFunc: ffi_bitkitcore_rust_future_complete_void, + freeFunc: ffi_bitkitcore_rust_future_free_void, + liftFunc: { $0 }, + errorHandler: FfiConverterTypePaykitError_lift + ) +} + + +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePubkyAuthenticatedTransport: FfiConverter { + + typealias FfiType = UnsafeMutableRawPointer + typealias SwiftType = PubkyAuthenticatedTransport + + public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> PubkyAuthenticatedTransport { + return PubkyAuthenticatedTransport(unsafeFromRawPointer: pointer) + } + + public static func lower(_ value: PubkyAuthenticatedTransport) -> UnsafeMutableRawPointer { + return value.uniffiClonePointer() + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PubkyAuthenticatedTransport { + let v: UInt64 = try readInt(&buf) + // The Rust code won't compile if a pointer won't fit in a UInt64. + // We have to go via `UInt` because that's the thing that's the size of a pointer. + let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v)) + if (ptr == nil) { + throw UniffiInternalError.unexpectedNullPointer + } + return try lift(ptr!) + } + + public static func write(_ value: PubkyAuthenticatedTransport, into buf: inout [UInt8]) { + // This fiddling is because `Int` is the thing that's the same size as a pointer. + // The Rust code won't compile if a pointer won't fit in a `UInt64`. + writeInt(&buf, UInt64(bitPattern: Int64(Int(bitPattern: lower(value))))) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePubkyAuthenticatedTransport_lift(_ pointer: UnsafeMutableRawPointer) throws -> PubkyAuthenticatedTransport { + return try FfiConverterTypePubkyAuthenticatedTransport.lift(pointer) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePubkyAuthenticatedTransport_lower(_ value: PubkyAuthenticatedTransport) -> UnsafeMutableRawPointer { + return FfiConverterTypePubkyAuthenticatedTransport.lower(value) +} + + + + + + +/** + * Unauthenticated transport wrapper for Paykit read operations. + */ +public protocol PubkyUnauthenticatedTransportProtocol: AnyObject, Sendable { + + /** + * Returns known contacts (follows) of a given public key. + * + * # Parameters + * - `key`: Public key to query for contacts + * + * # Returns + * - `Ok(Vec)` with list of known contacts + * - Returns empty vector if no contacts are stored + * - `Err` only on transport failures + */ + func getKnownContacts(key: PublicKey) async throws -> [PublicKey] + + /** + * Retrieves a specific payment endpoint for a payee and method. + * + * # Parameters + * - `payee`: Public key of the payee + * - `method`: Payment method identifier to query + * + * # Returns + * - `Ok(Some(EndpointData))` if the endpoint exists + * - `Ok(None)` if the endpoint is not published + * - `Err` only on transport failures + */ + func getPaymentEndpoint(payee: PublicKey, method: MethodId) async throws -> EndpointData? + + /** + * Retrieves all supported payment methods for a given payee. + * + * # Parameters + * - `payee`: Public key of the payee to query + * + * # Returns + * - `Ok(SupportedPayments)` with map of method IDs to endpoint data + * - Returns empty map if no endpoints are published + * - `Err` only on transport failures + */ + func getPaymentList(payee: PublicKey) async throws -> SupportedPayments + +} +/** + * Unauthenticated transport wrapper for Paykit read operations. + */ +open class PubkyUnauthenticatedTransport: PubkyUnauthenticatedTransportProtocol, @unchecked Sendable { + fileprivate let pointer: UnsafeMutableRawPointer! + + /// Used to instantiate a [FFIObject] without an actual pointer, for fakes in tests, mostly. +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public struct NoPointer { + public init() {} + } + + // TODO: We'd like this to be `private` but for Swifty reasons, + // we can't implement `FfiConverter` without making this `required` and we can't + // make it `required` without making it `public`. +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + required public init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) { + self.pointer = pointer + } + + // This constructor can be used to instantiate a fake object. + // - Parameter noPointer: Placeholder value so we can have a constructor separate from the default empty one that may be implemented for classes extending [FFIObject]. + // + // - Warning: + // Any object instantiated with this constructor cannot be passed to an actual Rust-backed object. Since there isn't a backing [Pointer] the FFI lower functions will crash. +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public init(noPointer: NoPointer) { + self.pointer = nil + } + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public func uniffiClonePointer() -> UnsafeMutableRawPointer { + return try! rustCall { uniffi_bitkitcore_fn_clone_pubkyunauthenticatedtransport(self.pointer, $0) } + } + /** + * Creates a new unauthenticated transport for reading public payment data. + */ +public convenience init()throws { + let pointer = + try rustCallWithError(FfiConverterTypePaykitError_lift) { + uniffi_bitkitcore_fn_constructor_pubkyunauthenticatedtransport_new($0 + ) +} + self.init(unsafeFromRawPointer: pointer) +} + + deinit { + guard let pointer = pointer else { + return + } + + try! rustCall { uniffi_bitkitcore_fn_free_pubkyunauthenticatedtransport(pointer, $0) } + } + + + + + /** + * Returns known contacts (follows) of a given public key. + * + * # Parameters + * - `key`: Public key to query for contacts + * + * # Returns + * - `Ok(Vec)` with list of known contacts + * - Returns empty vector if no contacts are stored + * - `Err` only on transport failures + */ +open func getKnownContacts(key: PublicKey)async throws -> [PublicKey] { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_known_contacts( + self.uniffiClonePointer(), + FfiConverterTypePublicKey_lower(key) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterSequenceTypePublicKey.lift, + errorHandler: FfiConverterTypePaykitError_lift + ) +} + + /** + * Retrieves a specific payment endpoint for a payee and method. + * + * # Parameters + * - `payee`: Public key of the payee + * - `method`: Payment method identifier to query + * + * # Returns + * - `Ok(Some(EndpointData))` if the endpoint exists + * - `Ok(None)` if the endpoint is not published + * - `Err` only on transport failures + */ +open func getPaymentEndpoint(payee: PublicKey, method: MethodId)async throws -> EndpointData? { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_endpoint( + self.uniffiClonePointer(), + FfiConverterTypePublicKey_lower(payee),FfiConverterTypeMethodId_lower(method) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterOptionTypeEndpointData.lift, + errorHandler: FfiConverterTypePaykitError_lift + ) +} + + /** + * Retrieves all supported payment methods for a given payee. + * + * # Parameters + * - `payee`: Public key of the payee to query + * + * # Returns + * - `Ok(SupportedPayments)` with map of method IDs to endpoint data + * - Returns empty map if no endpoints are published + * - `Err` only on transport failures + */ +open func getPaymentList(payee: PublicKey)async throws -> SupportedPayments { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_list( + self.uniffiClonePointer(), + FfiConverterTypePublicKey_lower(payee) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypeSupportedPayments_lift, + errorHandler: FfiConverterTypePaykitError_lift + ) +} + + +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePubkyUnauthenticatedTransport: FfiConverter { + + typealias FfiType = UnsafeMutableRawPointer + typealias SwiftType = PubkyUnauthenticatedTransport + + public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> PubkyUnauthenticatedTransport { + return PubkyUnauthenticatedTransport(unsafeFromRawPointer: pointer) + } + + public static func lower(_ value: PubkyUnauthenticatedTransport) -> UnsafeMutableRawPointer { + return value.uniffiClonePointer() + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PubkyUnauthenticatedTransport { + let v: UInt64 = try readInt(&buf) + // The Rust code won't compile if a pointer won't fit in a UInt64. + // We have to go via `UInt` because that's the thing that's the size of a pointer. + let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v)) + if (ptr == nil) { + throw UniffiInternalError.unexpectedNullPointer + } + return try lift(ptr!) + } + + public static func write(_ value: PubkyUnauthenticatedTransport, into buf: inout [UInt8]) { + // This fiddling is because `Int` is the thing that's the same size as a pointer. + // The Rust code won't compile if a pointer won't fit in a `UInt64`. + writeInt(&buf, UInt64(bitPattern: Int64(Int(bitPattern: lower(value))))) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePubkyUnauthenticatedTransport_lift(_ pointer: UnsafeMutableRawPointer) throws -> PubkyUnauthenticatedTransport { + return try FfiConverterTypePubkyUnauthenticatedTransport.lift(pointer) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePubkyUnauthenticatedTransport_lower(_ value: PubkyUnauthenticatedTransport) -> UnsafeMutableRawPointer { + return FfiConverterTypePubkyUnauthenticatedTransport.lower(value) +} + + + + /** * Account addresses */ @@ -2335,24 +2809,91 @@ public func FfiConverterTypeDeviceParams_lower(_ value: DeviceParams) -> RustBuf } -public struct ErrorData { - public var errorDetails: String +/** + * Serialized payload served by a payment endpoint (UTF-8 text such as JSON, LNURL, etc.). + */ +public struct EndpointData { + public var data: String // Default memberwise initializers are never public by default, so we // declare one manually. - public init(errorDetails: String) { - self.errorDetails = errorDetails + public init(data: String) { + self.data = data } } #if compiler(>=6) -extension ErrorData: Sendable {} +extension EndpointData: Sendable {} #endif -extension ErrorData: Equatable, Hashable { - public static func ==(lhs: ErrorData, rhs: ErrorData) -> Bool { - if lhs.errorDetails != rhs.errorDetails { +extension EndpointData: Equatable, Hashable { + public static func ==(lhs: EndpointData, rhs: EndpointData) -> Bool { + if lhs.data != rhs.data { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(data) + } +} + +extension EndpointData: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeEndpointData: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> EndpointData { + return + try EndpointData( + data: FfiConverterString.read(from: &buf) + ) + } + + public static func write(_ value: EndpointData, into buf: inout [UInt8]) { + FfiConverterString.write(value.data, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeEndpointData_lift(_ buf: RustBuffer) throws -> EndpointData { + return try FfiConverterTypeEndpointData.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeEndpointData_lower(_ value: EndpointData) -> RustBuffer { + return FfiConverterTypeEndpointData.lower(value) +} + + +public struct ErrorData { + public var errorDetails: String + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(errorDetails: String) { + self.errorDetails = errorDetails + } +} + +#if compiler(>=6) +extension ErrorData: Sendable {} +#endif + + +extension ErrorData: Equatable, Hashable { + public static func ==(lhs: ErrorData, rhs: ErrorData) -> Bool { + if lhs.errorDetails != rhs.errorDetails { return false } return true @@ -7018,6 +7559,73 @@ public func FfiConverterTypeMessageSignatureResponse_lower(_ value: MessageSigna } +/** + * Identifier for a payment method specification (e.g., "lightning", "onchain", "bolt11"). + */ +public struct MethodId { + public var id: String + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(id: String) { + self.id = id + } +} + +#if compiler(>=6) +extension MethodId: Sendable {} +#endif + + +extension MethodId: Equatable, Hashable { + public static func ==(lhs: MethodId, rhs: MethodId) -> Bool { + if lhs.id != rhs.id { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(id) + } +} + +extension MethodId: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeMethodId: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> MethodId { + return + try MethodId( + id: FfiConverterString.read(from: &buf) + ) + } + + public static func write(_ value: MethodId, into buf: inout [UInt8]) { + FfiConverterString.write(value.id, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeMethodId_lift(_ buf: RustBuffer) throws -> MethodId { + return try FfiConverterTypeMethodId.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeMethodId_lower(_ value: MethodId) -> RustBuffer { + return FfiConverterTypeMethodId.lower(value) +} + + /** * Multisig Redeem Script Type */ @@ -7443,6 +8051,107 @@ public func FfiConverterTypeOnchainActivity_lower(_ value: OnchainActivity) -> R } +/** + * Represents a parsed deeplink with Paykit session information + */ +public struct PaykitDeeplink { + /** + * The action to perform (e.g., "session", "payment", "connect") + */ + public var action: String + /** + * The session token if present + */ + public var sessionToken: String? + /** + * Additional parameters from the deeplink + */ + public var parameters: [String: String] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init( + /** + * The action to perform (e.g., "session", "payment", "connect") + */action: String, + /** + * The session token if present + */sessionToken: String?, + /** + * Additional parameters from the deeplink + */parameters: [String: String]) { + self.action = action + self.sessionToken = sessionToken + self.parameters = parameters + } +} + +#if compiler(>=6) +extension PaykitDeeplink: Sendable {} +#endif + + +extension PaykitDeeplink: Equatable, Hashable { + public static func ==(lhs: PaykitDeeplink, rhs: PaykitDeeplink) -> Bool { + if lhs.action != rhs.action { + return false + } + if lhs.sessionToken != rhs.sessionToken { + return false + } + if lhs.parameters != rhs.parameters { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(action) + hasher.combine(sessionToken) + hasher.combine(parameters) + } +} + +extension PaykitDeeplink: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePaykitDeeplink: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PaykitDeeplink { + return + try PaykitDeeplink( + action: FfiConverterString.read(from: &buf), + sessionToken: FfiConverterOptionString.read(from: &buf), + parameters: FfiConverterDictionaryStringString.read(from: &buf) + ) + } + + public static func write(_ value: PaykitDeeplink, into buf: inout [UInt8]) { + FfiConverterString.write(value.action, into: &buf) + FfiConverterOptionString.write(value.sessionToken, into: &buf) + FfiConverterDictionaryStringString.write(value.parameters, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePaykitDeeplink_lift(_ buf: RustBuffer) throws -> PaykitDeeplink { + return try FfiConverterTypePaykitDeeplink.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePaykitDeeplink_lower(_ value: PaykitDeeplink) -> RustBuffer { + return FfiConverterTypePaykitDeeplink.lower(value) +} + + /** * Payment request memo types */ @@ -8159,6 +8868,73 @@ public func FfiConverterTypePubkyAuth_lower(_ value: PubkyAuth) -> RustBuffer { } +/** + * Public key wrapper for Paykit operations. + */ +public struct PublicKey { + public var key: String + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(key: String) { + self.key = key + } +} + +#if compiler(>=6) +extension PublicKey: Sendable {} +#endif + + +extension PublicKey: Equatable, Hashable { + public static func ==(lhs: PublicKey, rhs: PublicKey) -> Bool { + if lhs.key != rhs.key { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(key) + } +} + +extension PublicKey: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePublicKey: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PublicKey { + return + try PublicKey( + key: FfiConverterString.read(from: &buf) + ) + } + + public static func write(_ value: PublicKey, into buf: inout [UInt8]) { + FfiConverterString.write(value.key, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePublicKey_lift(_ buf: RustBuffer) throws -> PublicKey { + return try FfiConverterTypePublicKey.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePublicKey_lower(_ value: PublicKey) -> RustBuffer { + return FfiConverterTypePublicKey.lower(value) +} + + /** * Public key response containing the derived public key information */ @@ -8564,49 +9340,311 @@ extension RefTxInput: Equatable, Hashable { if lhs.prevHash != rhs.prevHash { return false } - if lhs.prevIndex != rhs.prevIndex { + if lhs.prevIndex != rhs.prevIndex { + return false + } + if lhs.scriptSig != rhs.scriptSig { + return false + } + if lhs.sequence != rhs.sequence { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(prevHash) + hasher.combine(prevIndex) + hasher.combine(scriptSig) + hasher.combine(sequence) + } +} + +extension RefTxInput: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeRefTxInput: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RefTxInput { + return + try RefTxInput( + prevHash: FfiConverterString.read(from: &buf), + prevIndex: FfiConverterUInt32.read(from: &buf), + scriptSig: FfiConverterString.read(from: &buf), + sequence: FfiConverterUInt32.read(from: &buf) + ) + } + + public static func write(_ value: RefTxInput, into buf: inout [UInt8]) { + FfiConverterString.write(value.prevHash, into: &buf) + FfiConverterUInt32.write(value.prevIndex, into: &buf) + FfiConverterString.write(value.scriptSig, into: &buf) + FfiConverterUInt32.write(value.sequence, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeRefTxInput_lift(_ buf: RustBuffer) throws -> RefTxInput { + return try FfiConverterTypeRefTxInput.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeRefTxInput_lower(_ value: RefTxInput) -> RustBuffer { + return FfiConverterTypeRefTxInput.lower(value) +} + + +/** + * Reference transaction output (binary format) + */ +public struct RefTxOutput { + /** + * Amount in satoshis + */ + public var amount: UInt64 + /** + * Script public key (binary hex) + */ + public var scriptPubkey: String + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init( + /** + * Amount in satoshis + */amount: UInt64, + /** + * Script public key (binary hex) + */scriptPubkey: String) { + self.amount = amount + self.scriptPubkey = scriptPubkey + } +} + +#if compiler(>=6) +extension RefTxOutput: Sendable {} +#endif + + +extension RefTxOutput: Equatable, Hashable { + public static func ==(lhs: RefTxOutput, rhs: RefTxOutput) -> Bool { + if lhs.amount != rhs.amount { + return false + } + if lhs.scriptPubkey != rhs.scriptPubkey { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(amount) + hasher.combine(scriptPubkey) + } +} + +extension RefTxOutput: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeRefTxOutput: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RefTxOutput { + return + try RefTxOutput( + amount: FfiConverterUInt64.read(from: &buf), + scriptPubkey: FfiConverterString.read(from: &buf) + ) + } + + public static func write(_ value: RefTxOutput, into buf: inout [UInt8]) { + FfiConverterUInt64.write(value.amount, into: &buf) + FfiConverterString.write(value.scriptPubkey, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeRefTxOutput_lift(_ buf: RustBuffer) throws -> RefTxOutput { + return try FfiConverterTypeRefTxOutput.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeRefTxOutput_lower(_ value: RefTxOutput) -> RustBuffer { + return FfiConverterTypeRefTxOutput.lower(value) +} + + +/** + * Refund memo + */ +public struct RefundMemo { + /** + * Refund address + */ + public var address: String + /** + * MAC + */ + public var mac: String + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init( + /** + * Refund address + */address: String, + /** + * MAC + */mac: String) { + self.address = address + self.mac = mac + } +} + +#if compiler(>=6) +extension RefundMemo: Sendable {} +#endif + + +extension RefundMemo: Equatable, Hashable { + public static func ==(lhs: RefundMemo, rhs: RefundMemo) -> Bool { + if lhs.address != rhs.address { + return false + } + if lhs.mac != rhs.mac { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(address) + hasher.combine(mac) + } +} + +extension RefundMemo: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeRefundMemo: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RefundMemo { + return + try RefundMemo( + address: FfiConverterString.read(from: &buf), + mac: FfiConverterString.read(from: &buf) + ) + } + + public static func write(_ value: RefundMemo, into buf: inout [UInt8]) { + FfiConverterString.write(value.address, into: &buf) + FfiConverterString.write(value.mac, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeRefundMemo_lift(_ buf: RustBuffer) throws -> RefundMemo { + return try FfiConverterTypeRefundMemo.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeRefundMemo_lower(_ value: RefundMemo) -> RustBuffer { + return FfiConverterTypeRefundMemo.lower(value) +} + + +public struct ScannedPaykitSession { + public var url: String + public var action: String + public var token: String + public var parameters: [String: String] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(url: String, action: String, token: String, parameters: [String: String]) { + self.url = url + self.action = action + self.token = token + self.parameters = parameters + } +} + +#if compiler(>=6) +extension ScannedPaykitSession: Sendable {} +#endif + + +extension ScannedPaykitSession: Equatable, Hashable { + public static func ==(lhs: ScannedPaykitSession, rhs: ScannedPaykitSession) -> Bool { + if lhs.url != rhs.url { + return false + } + if lhs.action != rhs.action { return false } - if lhs.scriptSig != rhs.scriptSig { + if lhs.token != rhs.token { return false } - if lhs.sequence != rhs.sequence { + if lhs.parameters != rhs.parameters { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(prevHash) - hasher.combine(prevIndex) - hasher.combine(scriptSig) - hasher.combine(sequence) + hasher.combine(url) + hasher.combine(action) + hasher.combine(token) + hasher.combine(parameters) } } -extension RefTxInput: Codable {} +extension ScannedPaykitSession: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeRefTxInput: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RefTxInput { +public struct FfiConverterTypeScannedPaykitSession: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ScannedPaykitSession { return - try RefTxInput( - prevHash: FfiConverterString.read(from: &buf), - prevIndex: FfiConverterUInt32.read(from: &buf), - scriptSig: FfiConverterString.read(from: &buf), - sequence: FfiConverterUInt32.read(from: &buf) + try ScannedPaykitSession( + url: FfiConverterString.read(from: &buf), + action: FfiConverterString.read(from: &buf), + token: FfiConverterString.read(from: &buf), + parameters: FfiConverterDictionaryStringString.read(from: &buf) ) } - public static func write(_ value: RefTxInput, into buf: inout [UInt8]) { - FfiConverterString.write(value.prevHash, into: &buf) - FfiConverterUInt32.write(value.prevIndex, into: &buf) - FfiConverterString.write(value.scriptSig, into: &buf) - FfiConverterUInt32.write(value.sequence, into: &buf) + public static func write(_ value: ScannedPaykitSession, into buf: inout [UInt8]) { + FfiConverterString.write(value.url, into: &buf) + FfiConverterString.write(value.action, into: &buf) + FfiConverterString.write(value.token, into: &buf) + FfiConverterDictionaryStringString.write(value.parameters, into: &buf) } } @@ -8614,86 +9652,128 @@ public struct FfiConverterTypeRefTxInput: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeRefTxInput_lift(_ buf: RustBuffer) throws -> RefTxInput { - return try FfiConverterTypeRefTxInput.lift(buf) +public func FfiConverterTypeScannedPaykitSession_lift(_ buf: RustBuffer) throws -> ScannedPaykitSession { + return try FfiConverterTypeScannedPaykitSession.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeRefTxInput_lower(_ value: RefTxInput) -> RustBuffer { - return FfiConverterTypeRefTxInput.lower(value) +public func FfiConverterTypeScannedPaykitSession_lower(_ value: ScannedPaykitSession) -> RustBuffer { + return FfiConverterTypeScannedPaykitSession.lower(value) } /** - * Reference transaction output (binary format) + * Represents serializable session data that can be passed through a deeplink */ -public struct RefTxOutput { +public struct SessionData { /** - * Amount in satoshis + * The user's public key */ - public var amount: UInt64 + public var publicKey: String /** - * Script public key (binary hex) + * The user's secret key (encrypted or encoded) */ - public var scriptPubkey: String + public var secretKey: String + /** + * Optional homeserver URL + */ + public var homeserverUrl: String? + /** + * Session expiry timestamp (Unix timestamp) + */ + public var expiresAt: Int64? + /** + * Additional metadata + */ + public var metadata: String? // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Amount in satoshis - */amount: UInt64, + * The user's public key + */publicKey: String, /** - * Script public key (binary hex) - */scriptPubkey: String) { - self.amount = amount - self.scriptPubkey = scriptPubkey + * The user's secret key (encrypted or encoded) + */secretKey: String, + /** + * Optional homeserver URL + */homeserverUrl: String?, + /** + * Session expiry timestamp (Unix timestamp) + */expiresAt: Int64?, + /** + * Additional metadata + */metadata: String?) { + self.publicKey = publicKey + self.secretKey = secretKey + self.homeserverUrl = homeserverUrl + self.expiresAt = expiresAt + self.metadata = metadata } } #if compiler(>=6) -extension RefTxOutput: Sendable {} +extension SessionData: Sendable {} #endif -extension RefTxOutput: Equatable, Hashable { - public static func ==(lhs: RefTxOutput, rhs: RefTxOutput) -> Bool { - if lhs.amount != rhs.amount { +extension SessionData: Equatable, Hashable { + public static func ==(lhs: SessionData, rhs: SessionData) -> Bool { + if lhs.publicKey != rhs.publicKey { return false } - if lhs.scriptPubkey != rhs.scriptPubkey { + if lhs.secretKey != rhs.secretKey { + return false + } + if lhs.homeserverUrl != rhs.homeserverUrl { + return false + } + if lhs.expiresAt != rhs.expiresAt { + return false + } + if lhs.metadata != rhs.metadata { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(amount) - hasher.combine(scriptPubkey) + hasher.combine(publicKey) + hasher.combine(secretKey) + hasher.combine(homeserverUrl) + hasher.combine(expiresAt) + hasher.combine(metadata) } } -extension RefTxOutput: Codable {} +extension SessionData: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeRefTxOutput: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RefTxOutput { +public struct FfiConverterTypeSessionData: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SessionData { return - try RefTxOutput( - amount: FfiConverterUInt64.read(from: &buf), - scriptPubkey: FfiConverterString.read(from: &buf) + try SessionData( + publicKey: FfiConverterString.read(from: &buf), + secretKey: FfiConverterString.read(from: &buf), + homeserverUrl: FfiConverterOptionString.read(from: &buf), + expiresAt: FfiConverterOptionInt64.read(from: &buf), + metadata: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: RefTxOutput, into buf: inout [UInt8]) { - FfiConverterUInt64.write(value.amount, into: &buf) - FfiConverterString.write(value.scriptPubkey, into: &buf) + public static func write(_ value: SessionData, into buf: inout [UInt8]) { + FfiConverterString.write(value.publicKey, into: &buf) + FfiConverterString.write(value.secretKey, into: &buf) + FfiConverterOptionString.write(value.homeserverUrl, into: &buf) + FfiConverterOptionInt64.write(value.expiresAt, into: &buf) + FfiConverterOptionString.write(value.metadata, into: &buf) } } @@ -8701,86 +9781,72 @@ public struct FfiConverterTypeRefTxOutput: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeRefTxOutput_lift(_ buf: RustBuffer) throws -> RefTxOutput { - return try FfiConverterTypeRefTxOutput.lift(buf) +public func FfiConverterTypeSessionData_lift(_ buf: RustBuffer) throws -> SessionData { + return try FfiConverterTypeSessionData.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeRefTxOutput_lower(_ value: RefTxOutput) -> RustBuffer { - return FfiConverterTypeRefTxOutput.lower(value) +public func FfiConverterTypeSessionData_lower(_ value: SessionData) -> RustBuffer { + return FfiConverterTypeSessionData.lower(value) } /** - * Refund memo + * Represents a session token that can be passed through deeplinks */ -public struct RefundMemo { - /** - * Refund address - */ - public var address: String +public struct SessionToken { /** - * MAC + * Base64 URL-safe encoded session data */ - public var mac: String + public var token: String // Default memberwise initializers are never public by default, so we // declare one manually. public init( /** - * Refund address - */address: String, - /** - * MAC - */mac: String) { - self.address = address - self.mac = mac + * Base64 URL-safe encoded session data + */token: String) { + self.token = token } } #if compiler(>=6) -extension RefundMemo: Sendable {} +extension SessionToken: Sendable {} #endif -extension RefundMemo: Equatable, Hashable { - public static func ==(lhs: RefundMemo, rhs: RefundMemo) -> Bool { - if lhs.address != rhs.address { - return false - } - if lhs.mac != rhs.mac { +extension SessionToken: Equatable, Hashable { + public static func ==(lhs: SessionToken, rhs: SessionToken) -> Bool { + if lhs.token != rhs.token { return false } return true } public func hash(into hasher: inout Hasher) { - hasher.combine(address) - hasher.combine(mac) + hasher.combine(token) } } -extension RefundMemo: Codable {} +extension SessionToken: Codable {} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeRefundMemo: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RefundMemo { +public struct FfiConverterTypeSessionToken: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SessionToken { return - try RefundMemo( - address: FfiConverterString.read(from: &buf), - mac: FfiConverterString.read(from: &buf) + try SessionToken( + token: FfiConverterString.read(from: &buf) ) } - public static func write(_ value: RefundMemo, into buf: inout [UInt8]) { - FfiConverterString.write(value.address, into: &buf) - FfiConverterString.write(value.mac, into: &buf) + public static func write(_ value: SessionToken, into buf: inout [UInt8]) { + FfiConverterString.write(value.token, into: &buf) } } @@ -8788,15 +9854,15 @@ public struct FfiConverterTypeRefundMemo: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeRefundMemo_lift(_ buf: RustBuffer) throws -> RefundMemo { - return try FfiConverterTypeRefundMemo.lift(buf) +public func FfiConverterTypeSessionToken_lift(_ buf: RustBuffer) throws -> SessionToken { + return try FfiConverterTypeSessionToken.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeRefundMemo_lower(_ value: RefundMemo) -> RustBuffer { - return FfiConverterTypeRefundMemo.lower(value) +public func FfiConverterTypeSessionToken_lower(_ value: SessionToken) -> RustBuffer { + return FfiConverterTypeSessionToken.lower(value) } @@ -8901,6 +9967,73 @@ public func FfiConverterTypeSignedTransactionResponse_lower(_ value: SignedTrans } +/** + * Collection of supported payment entries keyed by method identifiers. + */ +public struct SupportedPayments { + public var entries: [String: EndpointData] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(entries: [String: EndpointData]) { + self.entries = entries + } +} + +#if compiler(>=6) +extension SupportedPayments: Sendable {} +#endif + + +extension SupportedPayments: Equatable, Hashable { + public static func ==(lhs: SupportedPayments, rhs: SupportedPayments) -> Bool { + if lhs.entries != rhs.entries { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(entries) + } +} + +extension SupportedPayments: Codable {} + + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeSupportedPayments: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SupportedPayments { + return + try SupportedPayments( + entries: FfiConverterDictionaryStringTypeEndpointData.read(from: &buf) + ) + } + + public static func write(_ value: SupportedPayments, into buf: inout [UInt8]) { + FfiConverterDictionaryStringTypeEndpointData.write(value.entries, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSupportedPayments_lift(_ buf: RustBuffer) throws -> SupportedPayments { + return try FfiConverterTypeSupportedPayments.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSupportedPayments_lower(_ value: SupportedPayments) -> RustBuffer { + return FfiConverterTypeSupportedPayments.lower(value) +} + + /** * Text memo */ @@ -12656,9 +13789,133 @@ public struct FfiConverterTypeNetworkType: FfiConverterRustBuffer { writeInt(&buf, Int32(3)) - case .signet: + case .signet: + writeInt(&buf, Int32(4)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNetworkType_lift(_ buf: RustBuffer) throws -> NetworkType { + return try FfiConverterTypeNetworkType.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeNetworkType_lower(_ value: NetworkType) -> RustBuffer { + return FfiConverterTypeNetworkType.lower(value) +} + + +extension NetworkType: Equatable, Hashable {} + +extension NetworkType: Codable {} + + + + + + + +/** + * Domain-specific error type for Paykit operations. + */ +public enum PaykitError: Swift.Error { + + + + case Unimplemented(String + ) + case Transport(String + ) + case InvalidPublicKey(String + ) + case InvalidMethodId(String + ) + case InvalidEndpointData(String + ) + case SessionError(String + ) +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePaykitError: FfiConverterRustBuffer { + typealias SwiftType = PaykitError + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PaykitError { + let variant: Int32 = try readInt(&buf) + switch variant { + + + + + case 1: return .Unimplemented( + try FfiConverterString.read(from: &buf) + ) + case 2: return .Transport( + try FfiConverterString.read(from: &buf) + ) + case 3: return .InvalidPublicKey( + try FfiConverterString.read(from: &buf) + ) + case 4: return .InvalidMethodId( + try FfiConverterString.read(from: &buf) + ) + case 5: return .InvalidEndpointData( + try FfiConverterString.read(from: &buf) + ) + case 6: return .SessionError( + try FfiConverterString.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: PaykitError, into buf: inout [UInt8]) { + switch value { + + + + + + case let .Unimplemented(v1): + writeInt(&buf, Int32(1)) + FfiConverterString.write(v1, into: &buf) + + + case let .Transport(v1): + writeInt(&buf, Int32(2)) + FfiConverterString.write(v1, into: &buf) + + + case let .InvalidPublicKey(v1): + writeInt(&buf, Int32(3)) + FfiConverterString.write(v1, into: &buf) + + + case let .InvalidMethodId(v1): writeInt(&buf, Int32(4)) + FfiConverterString.write(v1, into: &buf) + + + case let .InvalidEndpointData(v1): + writeInt(&buf, Int32(5)) + FfiConverterString.write(v1, into: &buf) + + case let .SessionError(v1): + writeInt(&buf, Int32(6)) + FfiConverterString.write(v1, into: &buf) + } } } @@ -12667,25 +13924,32 @@ public struct FfiConverterTypeNetworkType: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeNetworkType_lift(_ buf: RustBuffer) throws -> NetworkType { - return try FfiConverterTypeNetworkType.lift(buf) +public func FfiConverterTypePaykitError_lift(_ buf: RustBuffer) throws -> PaykitError { + return try FfiConverterTypePaykitError.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeNetworkType_lower(_ value: NetworkType) -> RustBuffer { - return FfiConverterTypeNetworkType.lower(value) +public func FfiConverterTypePaykitError_lower(_ value: PaykitError) -> RustBuffer { + return FfiConverterTypePaykitError.lower(value) } -extension NetworkType: Equatable, Hashable {} +extension PaykitError: Equatable, Hashable {} -extension NetworkType: Codable {} +extension PaykitError: Codable {} +extension PaykitError: Foundation.LocalizedError { + public var errorDescription: String? { + String(reflecting: self) + } +} + + // Note that we don't yet support `indirect` for enums. @@ -12850,6 +14114,8 @@ public enum Scanner { ) case pubkyAuth(data: String ) + case paykitSession(data: ScannedPaykitSession + ) case lnurlChannel(data: LnurlChannelData ) case lnurlAuth(data: LnurlAuthData @@ -12890,25 +14156,28 @@ public struct FfiConverterTypeScanner: FfiConverterRustBuffer { case 3: return .pubkyAuth(data: try FfiConverterString.read(from: &buf) ) - case 4: return .lnurlChannel(data: try FfiConverterTypeLnurlChannelData.read(from: &buf) + case 4: return .paykitSession(data: try FfiConverterTypeScannedPaykitSession.read(from: &buf) + ) + + case 5: return .lnurlChannel(data: try FfiConverterTypeLnurlChannelData.read(from: &buf) ) - case 5: return .lnurlAuth(data: try FfiConverterTypeLnurlAuthData.read(from: &buf) + case 6: return .lnurlAuth(data: try FfiConverterTypeLnurlAuthData.read(from: &buf) ) - case 6: return .lnurlWithdraw(data: try FfiConverterTypeLnurlWithdrawData.read(from: &buf) + case 7: return .lnurlWithdraw(data: try FfiConverterTypeLnurlWithdrawData.read(from: &buf) ) - case 7: return .lnurlAddress(data: try FfiConverterTypeLnurlAddressData.read(from: &buf) + case 8: return .lnurlAddress(data: try FfiConverterTypeLnurlAddressData.read(from: &buf) ) - case 8: return .lnurlPay(data: try FfiConverterTypeLnurlPayData.read(from: &buf) + case 9: return .lnurlPay(data: try FfiConverterTypeLnurlPayData.read(from: &buf) ) - case 9: return .nodeId(url: try FfiConverterString.read(from: &buf), network: try FfiConverterTypeNetworkType.read(from: &buf) + case 10: return .nodeId(url: try FfiConverterString.read(from: &buf), network: try FfiConverterTypeNetworkType.read(from: &buf) ) - case 10: return .gift(code: try FfiConverterString.read(from: &buf), amount: try FfiConverterUInt64.read(from: &buf) + case 11: return .gift(code: try FfiConverterString.read(from: &buf), amount: try FfiConverterUInt64.read(from: &buf) ) default: throw UniffiInternalError.unexpectedEnumCase @@ -12934,39 +14203,44 @@ public struct FfiConverterTypeScanner: FfiConverterRustBuffer { FfiConverterString.write(data, into: &buf) - case let .lnurlChannel(data): + case let .paykitSession(data): writeInt(&buf, Int32(4)) + FfiConverterTypeScannedPaykitSession.write(data, into: &buf) + + + case let .lnurlChannel(data): + writeInt(&buf, Int32(5)) FfiConverterTypeLnurlChannelData.write(data, into: &buf) case let .lnurlAuth(data): - writeInt(&buf, Int32(5)) + writeInt(&buf, Int32(6)) FfiConverterTypeLnurlAuthData.write(data, into: &buf) case let .lnurlWithdraw(data): - writeInt(&buf, Int32(6)) + writeInt(&buf, Int32(7)) FfiConverterTypeLnurlWithdrawData.write(data, into: &buf) case let .lnurlAddress(data): - writeInt(&buf, Int32(7)) + writeInt(&buf, Int32(8)) FfiConverterTypeLnurlAddressData.write(data, into: &buf) case let .lnurlPay(data): - writeInt(&buf, Int32(8)) + writeInt(&buf, Int32(9)) FfiConverterTypeLnurlPayData.write(data, into: &buf) case let .nodeId(url,network): - writeInt(&buf, Int32(9)) + writeInt(&buf, Int32(10)) FfiConverterString.write(url, into: &buf) FfiConverterTypeNetworkType.write(network, into: &buf) case let .gift(code,amount): - writeInt(&buf, Int32(10)) + writeInt(&buf, Int32(11)) FfiConverterString.write(code, into: &buf) FfiConverterUInt64.write(amount, into: &buf) @@ -13883,6 +15157,30 @@ fileprivate struct FfiConverterOptionUInt64: FfiConverterRustBuffer { } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionInt64: FfiConverterRustBuffer { + typealias SwiftType = Int64? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterInt64.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterInt64.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -14123,6 +15421,30 @@ fileprivate struct FfiConverterOptionTypeDeviceParams: FfiConverterRustBuffer { } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeEndpointData: FfiConverterRustBuffer { + typealias SwiftType = EndpointData? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeEndpointData.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeEndpointData.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -15801,6 +17123,31 @@ fileprivate struct FfiConverterSequenceTypePrecomposedTransaction: FfiConverterR } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypePublicKey: FfiConverterRustBuffer { + typealias SwiftType = [PublicKey] + + public static func write(_ value: [PublicKey], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypePublicKey.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [PublicKey] { + let len: Int32 = try readInt(&buf) + var seq = [PublicKey]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypePublicKey.read(from: &buf)) + } + return seq + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -16026,6 +17373,32 @@ fileprivate struct FfiConverterDictionaryStringString: FfiConverterRustBuffer { return dict } } + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterDictionaryStringTypeEndpointData: FfiConverterRustBuffer { + public static func write(_ value: [String: EndpointData], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for (key, value) in value { + FfiConverterString.write(key, into: &buf) + FfiConverterTypeEndpointData.write(value, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [String: EndpointData] { + let len: Int32 = try readInt(&buf) + var dict = [String: EndpointData]() + dict.reserveCapacity(Int(len)) + for _ in 0.. String { + return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypePaykitError_lift) { + uniffi_bitkitcore_fn_func_create_deeplink_from_token( + FfiConverterString.lower(baseUrl), + FfiConverterString.lower(action), + FfiConverterTypeSessionToken_lower(token), + FfiConverterOptionDictionaryStringString.lower(additionalParams),$0 + ) +}) +} public func createOrder(lspBalanceSat: UInt64, channelExpiryWeeks: UInt32, options: CreateOrderOptions?)async throws -> IBtOrder { return try await uniffiRustCallAsync( @@ -16185,6 +17591,62 @@ public func createOrder(lspBalanceSat: UInt64, channelExpiryWeeks: UInt32, optio errorHandler: FfiConverterTypeBlocktankError_lift ) } +/** + * Creates a session request URL to send to Pubky Ring for authentication. + * + * This generates a URL that Bitkit displays as a QR code or uses to open Pubky Ring. + * When Pubky Ring completes authentication, it will return the session data + * via the provided callback URL. + * + * # Parameters + * - `callback_url`: The URL scheme and path where Pubky Ring should return the session. + * Example: "bitkit://paykit/session-data" or "bitkit://session" + * - `additional_params`: Optional additional parameters to include in the request URL + * + * # Returns + * A URL string like: `pubkyring://session?callback=bitkit%3A%2F%2Fpaykit%2Fsession-data` + * + * # Example + * ``` + * // Generate URL for QR code or "Open Pubky Ring" button + * let request_url = create_pubky_ring_session_request( + * "bitkit://paykit/session-data".to_string(), + * None + * )?; + * // Result: "pubkyring://session?callback=bitkit%3A%2F%2Fpaykit%2Fsession-data" + * + * // With additional parameters + * let mut params = HashMap::new(); + * params.insert("app_name".to_string(), "Bitkit".to_string()); + * let request_url = create_pubky_ring_session_request( + * "bitkit://paykit/session-data".to_string(), + * Some(params) + * )?; + * ``` + */ +public func createPubkyRingSessionRequest(callbackUrl: String, additionalParams: [String: String]?)throws -> String { + return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypePaykitError_lift) { + uniffi_bitkitcore_fn_func_create_pubky_ring_session_request( + FfiConverterString.lower(callbackUrl), + FfiConverterOptionDictionaryStringString.lower(additionalParams),$0 + ) +}) +} +/** + * Helper function to create a session token from raw keypair data. + * + * This is useful when you have the keypair but need to create a shareable token. + */ +public func createSessionTokenFromKeypair(publicKey: String, secretKey: String, homeserverUrl: String?, expiresInSeconds: Int64?)throws -> SessionToken { + return try FfiConverterTypeSessionToken_lift(try rustCallWithError(FfiConverterTypePaykitError_lift) { + uniffi_bitkitcore_fn_func_create_session_token_from_keypair( + FfiConverterString.lower(publicKey), + FfiConverterString.lower(secretKey), + FfiConverterOptionString.lower(homeserverUrl), + FfiConverterOptionInt64.lower(expiresInSeconds),$0 + ) +}) +} public func createWithdrawCallbackUrl(k1: String, callback: String, paymentRequest: String)throws -> String { return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeLnurlError_lift) { uniffi_bitkitcore_fn_func_create_withdraw_callback_url( @@ -16254,6 +17716,23 @@ public func derivePrivateKey(mnemonicPhrase: String, derivationPathStr: String?, ) }) } +/** + * Deserializes a session token back into session data. + * + * # Example + * ``` + * let token = SessionToken::new("base64_encoded_session_data"); + * let session_data = deserialize_token_to_session(token)?; + * // Now you have the session data back + * ``` + */ +public func deserializeTokenToSession(token: SessionToken)throws -> SessionData { + return try FfiConverterTypeSessionData_lift(try rustCallWithError(FfiConverterTypePaykitError_lift) { + uniffi_bitkitcore_fn_func_deserialize_token_to_session( + FfiConverterTypeSessionToken_lower(token),$0 + ) +}) +} public func entropyToMnemonic(entropy: Data)throws -> String { return try FfiConverterString.lift(try rustCallWithError(FfiConverterTypeAddressError_lift) { uniffi_bitkitcore_fn_func_entropy_to_mnemonic( @@ -16428,6 +17907,42 @@ public func getInfo(refresh: Bool?)async throws -> IBtInfo? { errorHandler: FfiConverterTypeBlocktankError_lift ) } +/** + * Returns known contacts (follows) of a given public key. + * + * # Parameters + * - `reader`: Unauthenticated transport for reading public data + * - `key`: Public key to query for contacts + * + * # Returns + * - `Ok(Vec)` with list of known contacts + * - Returns empty vector if no contacts are stored + * - `Err` only on transport failures + * + * # Example + * ``` + * let reader = PubkyUnauthenticatedTransport::new()?; + * let user = PublicKey { key: "...".to_string() }; + * let contacts = get_known_contacts(&reader, &user).await?; + * for contact in contacts { + * println!("Contact: {}", contact.key); + * } + * ``` + */ +public func getKnownContacts(reader: PubkyUnauthenticatedTransport, key: PublicKey)async throws -> [PublicKey] { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_get_known_contacts(FfiConverterTypePubkyUnauthenticatedTransport_lower(reader),FfiConverterTypePublicKey_lower(key) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterSequenceTypePublicKey.lift, + errorHandler: FfiConverterTypePaykitError_lift + ) +} public func getLnurlInvoice(address: String, amountSatoshis: UInt64)async throws -> String { return try await uniffiRustCallAsync( @@ -16484,6 +17999,79 @@ public func getPayment(paymentId: String)async throws -> IBtBolt11Invoice { errorHandler: FfiConverterTypeBlocktankError_lift ) } +/** + * Retrieves a specific payment endpoint for a payee and method. + * + * # Parameters + * - `reader`: Unauthenticated transport for reading public data + * - `payee`: Public key of the payee + * - `method`: Payment method identifier to query + * + * # Returns + * - `Ok(Some(EndpointData))` if the endpoint exists + * - `Ok(None)` if the endpoint is not published + * - `Err` only on transport failures + * + * # Example + * ``` + * let reader = PubkyUnauthenticatedTransport::new()?; + * let payee = PublicKey { key: "...".to_string() }; + * let method = MethodId { id: "lightning".to_string() }; + * if let Some(endpoint) = get_payment_endpoint(&reader, &payee, &method).await? { + * println!("Lightning endpoint: {}", endpoint.data); + * } + * ``` + */ +public func getPaymentEndpoint(reader: PubkyUnauthenticatedTransport, payee: PublicKey, method: MethodId)async throws -> EndpointData? { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_get_payment_endpoint(FfiConverterTypePubkyUnauthenticatedTransport_lower(reader),FfiConverterTypePublicKey_lower(payee),FfiConverterTypeMethodId_lower(method) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterOptionTypeEndpointData.lift, + errorHandler: FfiConverterTypePaykitError_lift + ) +} +/** + * Retrieves all supported payment methods for a given payee. + * + * # Parameters + * - `reader`: Unauthenticated transport for reading public data + * - `payee`: Public key of the payee to query + * + * # Returns + * - `Ok(SupportedPayments)` with map of method IDs to endpoint data + * - Returns empty map if no endpoints are published + * - `Err` only on transport failures + * + * # Example + * ``` + * let reader = PubkyUnauthenticatedTransport::new()?; + * let payee = PublicKey { key: "...".to_string() }; + * let payments = get_payment_list(&reader, &payee).await?; + * for (method_id, data) in payments.entries { + * println!("Method: {}, Data: {}", method_id, data.data); + * } + * ``` + */ +public func getPaymentList(reader: PubkyUnauthenticatedTransport, payee: PublicKey)async throws -> SupportedPayments { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_get_payment_list(FfiConverterTypePubkyUnauthenticatedTransport_lower(reader),FfiConverterTypePublicKey_lower(payee) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_rust_buffer, + completeFunc: ffi_bitkitcore_rust_future_complete_rust_buffer, + freeFunc: ffi_bitkitcore_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypeSupportedPayments_lift, + errorHandler: FfiConverterTypePaykitError_lift + ) +} public func getPreActivityMetadata(searchKey: String, searchByAddress: Bool)throws -> PreActivityMetadata? { return try FfiConverterOptionTypePreActivityMetadata.lift(try rustCallWithError(FfiConverterTypeActivityError_lift) { uniffi_bitkitcore_fn_func_get_pre_activity_metadata( @@ -16597,6 +18185,29 @@ public func openChannel(orderId: String, connectionString: String)async throws errorHandler: FfiConverterTypeBlocktankError_lift ) } +/** + * Parses a deeplink URL into a PaykitDeeplink structure. + * + * # Supported URL Formats + * - `myapp://paykit/session?token=` + * - `myapp://paykit/connect?token=&return_url=` + * - `https://myapp.com/paykit/session?token=` + * + * # Example + * ``` + * let url = "myapp://paykit/session?token=eyJwdWJsaWNfa2V5IjoiLi4uIn0"; + * let deeplink = parse_paykit_deeplink(url)?; + * assert_eq!(deeplink.action, "session"); + * assert!(deeplink.session_token.is_some()); + * ``` + */ +public func parsePaykitDeeplink(url: String)throws -> PaykitDeeplink { + return try FfiConverterTypePaykitDeeplink_lift(try rustCallWithError(FfiConverterTypePaykitError_lift) { + uniffi_bitkitcore_fn_func_parse_paykit_deeplink( + FfiConverterString.lower(url),$0 + ) +}) +} /** * Refresh all active CJIT entries in the database with latest data from the LSP */ @@ -16722,6 +18333,31 @@ public func removeClosedChannelById(channelId: String)throws -> Bool { ) }) } +/** + * Removes a payment endpoint via the authenticated transport. + * + * # Parameters + * - `client`: Authenticated transport client + * - `method`: Payment method identifier to remove + * + * # Returns + * - `Ok(())` on successful removal + * - `Err` if the endpoint doesn't exist or transport fails + */ +public func removePaymentEndpoint(client: PubkyAuthenticatedTransport, method: MethodId)async throws { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_remove_payment_endpoint(FfiConverterTypePubkyAuthenticatedTransport_lower(client),FfiConverterTypeMethodId_lower(method) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_void, + completeFunc: ffi_bitkitcore_rust_future_complete_void, + freeFunc: ffi_bitkitcore_rust_future_free_void, + liftFunc: { $0 }, + errorHandler: FfiConverterTypePaykitError_lift + ) +} public func removePreActivityMetadataTags(paymentId: String, tags: [String])throws {try rustCallWithError(FfiConverterTypeActivityError_lift) { uniffi_bitkitcore_fn_func_remove_pre_activity_metadata_tags( FfiConverterString.lower(paymentId), @@ -16742,6 +18378,65 @@ public func resetPreActivityMetadataTags(paymentId: String)throws {try rustCal ) } } +/** + * Serializes session data into a token string suitable for deeplinks. + * + * # Security Considerations + * - The secret key should be encrypted before serialization + * - Use HTTPS/secure channels when transmitting + * - Consider adding expiration times + * - Implement token rotation for long-lived sessions + * + * # Example + * ``` + * let session_data = SessionData { + * public_key: "user_public_key".to_string(), + * secret_key: "encrypted_secret".to_string(), + * homeserver_url: Some("https://homeserver.example".to_string()), + * expires_at: Some(1234567890), + * metadata: None, + * }; + * + * let token = serialize_session_to_token(session_data)?; + * // token.token can now be passed through a deeplink + * ``` + */ +public func serializeSessionToToken(sessionData: SessionData)throws -> SessionToken { + return try FfiConverterTypeSessionToken_lift(try rustCallWithError(FfiConverterTypePaykitError_lift) { + uniffi_bitkitcore_fn_func_serialize_session_to_token( + FfiConverterTypeSessionData_lower(sessionData),$0 + ) +}) +} +/** + * Stores or updates a payment endpoint via the authenticated transport. + * + * # Parameters + * - `client`: Authenticated transport client + * - `method`: Payment method identifier (e.g., "lightning", "onchain") + * - `data`: Endpoint data payload (UTF-8 JSON or other text format) + * + * # Example + * ``` + * let method = MethodId { id: "lightning".to_string() }; + * let data = EndpointData { data: r#"{"bolt11":"lnbc..."}"#.to_string() }; + * set_payment_endpoint(&client, method, data).await?; + * ``` + */ +public func setPaymentEndpoint(client: PubkyAuthenticatedTransport, method: MethodId, data: EndpointData)async throws { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_bitkitcore_fn_func_set_payment_endpoint(FfiConverterTypePubkyAuthenticatedTransport_lower(client),FfiConverterTypeMethodId_lower(method),FfiConverterTypeEndpointData_lower(data) + ) + }, + pollFunc: ffi_bitkitcore_rust_future_poll_void, + completeFunc: ffi_bitkitcore_rust_future_complete_void, + freeFunc: ffi_bitkitcore_rust_future_free_void, + liftFunc: { $0 }, + errorHandler: FfiConverterTypePaykitError_lift + ) +} public func testNotification(deviceToken: String, secretMessage: String, notificationType: String?, customUrl: String?)async throws -> String { return try await uniffiRustCallAsync( @@ -17014,6 +18709,18 @@ public func validateMnemonic(mnemonicPhrase: String)throws {try rustCallWithEr ) } } +/** + * Validates a deeplink URL without processing it. + * + * Use this to check if a URL is a valid Paykit deeplink before handling it. + */ +public func validatePaykitDeeplink(url: String)throws -> Bool { + return try FfiConverterBool.lift(try rustCallWithError(FfiConverterTypePaykitError_lift) { + uniffi_bitkitcore_fn_func_validate_paykit_deeplink( + FfiConverterString.lower(url),$0 + ) +}) +} public func wipeAllClosedChannels()throws {try rustCallWithError(FfiConverterTypeActivityError_lift) { uniffi_bitkitcore_fn_func_wipe_all_closed_channels($0 ) @@ -17079,9 +18786,18 @@ private let initializationResult: InitializationResult = { if (uniffi_bitkitcore_checksum_func_create_cjit_entry() != 51504) { return InitializationResult.apiChecksumMismatch } + if (uniffi_bitkitcore_checksum_func_create_deeplink_from_token() != 51091) { + return InitializationResult.apiChecksumMismatch + } if (uniffi_bitkitcore_checksum_func_create_order() != 33461) { return InitializationResult.apiChecksumMismatch } + if (uniffi_bitkitcore_checksum_func_create_pubky_ring_session_request() != 2842) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_create_session_token_from_keypair() != 61582) { + return InitializationResult.apiChecksumMismatch + } if (uniffi_bitkitcore_checksum_func_create_withdraw_callback_url() != 39350) { return InitializationResult.apiChecksumMismatch } @@ -17103,6 +18819,9 @@ private let initializationResult: InitializationResult = { if (uniffi_bitkitcore_checksum_func_derive_private_key() != 25155) { return InitializationResult.apiChecksumMismatch } + if (uniffi_bitkitcore_checksum_func_deserialize_token_to_session() != 9427) { + return InitializationResult.apiChecksumMismatch + } if (uniffi_bitkitcore_checksum_func_entropy_to_mnemonic() != 26123) { return InitializationResult.apiChecksumMismatch } @@ -17160,6 +18879,9 @@ private let initializationResult: InitializationResult = { if (uniffi_bitkitcore_checksum_func_get_info() != 43607) { return InitializationResult.apiChecksumMismatch } + if (uniffi_bitkitcore_checksum_func_get_known_contacts() != 14867) { + return InitializationResult.apiChecksumMismatch + } if (uniffi_bitkitcore_checksum_func_get_lnurl_invoice() != 5475) { return InitializationResult.apiChecksumMismatch } @@ -17172,6 +18894,12 @@ private let initializationResult: InitializationResult = { if (uniffi_bitkitcore_checksum_func_get_payment() != 29170) { return InitializationResult.apiChecksumMismatch } + if (uniffi_bitkitcore_checksum_func_get_payment_endpoint() != 60834) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_get_payment_list() != 49866) { + return InitializationResult.apiChecksumMismatch + } if (uniffi_bitkitcore_checksum_func_get_pre_activity_metadata() != 53126) { return InitializationResult.apiChecksumMismatch } @@ -17208,6 +18936,9 @@ private let initializationResult: InitializationResult = { if (uniffi_bitkitcore_checksum_func_open_channel() != 21402) { return InitializationResult.apiChecksumMismatch } + if (uniffi_bitkitcore_checksum_func_parse_paykit_deeplink() != 40846) { + return InitializationResult.apiChecksumMismatch + } if (uniffi_bitkitcore_checksum_func_refresh_active_cjit_entries() != 5324) { return InitializationResult.apiChecksumMismatch } @@ -17235,6 +18966,9 @@ private let initializationResult: InitializationResult = { if (uniffi_bitkitcore_checksum_func_remove_closed_channel_by_id() != 17150) { return InitializationResult.apiChecksumMismatch } + if (uniffi_bitkitcore_checksum_func_remove_payment_endpoint() != 692) { + return InitializationResult.apiChecksumMismatch + } if (uniffi_bitkitcore_checksum_func_remove_pre_activity_metadata_tags() != 1991) { return InitializationResult.apiChecksumMismatch } @@ -17244,6 +18978,12 @@ private let initializationResult: InitializationResult = { if (uniffi_bitkitcore_checksum_func_reset_pre_activity_metadata_tags() != 34703) { return InitializationResult.apiChecksumMismatch } + if (uniffi_bitkitcore_checksum_func_serialize_session_to_token() != 52557) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_func_set_payment_endpoint() != 19775) { + return InitializationResult.apiChecksumMismatch + } if (uniffi_bitkitcore_checksum_func_test_notification() != 32857) { return InitializationResult.apiChecksumMismatch } @@ -17316,12 +19056,36 @@ private let initializationResult: InitializationResult = { if (uniffi_bitkitcore_checksum_func_validate_mnemonic() != 31005) { return InitializationResult.apiChecksumMismatch } + if (uniffi_bitkitcore_checksum_func_validate_paykit_deeplink() != 64617) { + return InitializationResult.apiChecksumMismatch + } if (uniffi_bitkitcore_checksum_func_wipe_all_closed_channels() != 41511) { return InitializationResult.apiChecksumMismatch } if (uniffi_bitkitcore_checksum_func_wipe_all_databases() != 54605) { return InitializationResult.apiChecksumMismatch } + if (uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_remove_payment_endpoint() != 6181) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_set_payment_endpoint() != 9801) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_known_contacts() != 59528) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_endpoint() != 53072) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_list() != 50101) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_constructor_pubkyauthenticatedtransport_new() != 38771) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_bitkitcore_checksum_constructor_pubkyunauthenticatedtransport_new() != 43061) { + return InitializationResult.apiChecksumMismatch + } return InitializationResult.ok }() diff --git a/bindings/ios/bitkitcoreFFI.h b/bindings/ios/bitkitcoreFFI.h index 4562536..9c1c486 100644 --- a/bindings/ios/bitkitcoreFFI.h +++ b/bindings/ios/bitkitcoreFFI.h @@ -250,6 +250,63 @@ typedef struct UniffiForeignFutureStructVoid { typedef void (*UniffiForeignFutureCompleteVoid)(uint64_t, UniffiForeignFutureStructVoid ); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_PUBKYAUTHENTICATEDTRANSPORT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_PUBKYAUTHENTICATEDTRANSPORT +void*_Nonnull uniffi_bitkitcore_fn_clone_pubkyauthenticatedtransport(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FREE_PUBKYAUTHENTICATEDTRANSPORT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FREE_PUBKYAUTHENTICATEDTRANSPORT +void uniffi_bitkitcore_fn_free_pubkyauthenticatedtransport(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CONSTRUCTOR_PUBKYAUTHENTICATEDTRANSPORT_NEW +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CONSTRUCTOR_PUBKYAUTHENTICATEDTRANSPORT_NEW +void*_Nonnull uniffi_bitkitcore_fn_constructor_pubkyauthenticatedtransport_new(RustCallStatus *_Nonnull out_status + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYAUTHENTICATEDTRANSPORT_REMOVE_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYAUTHENTICATEDTRANSPORT_REMOVE_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_remove_payment_endpoint(void*_Nonnull ptr, RustBuffer method +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYAUTHENTICATEDTRANSPORT_SET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYAUTHENTICATEDTRANSPORT_SET_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_set_payment_endpoint(void*_Nonnull ptr, RustBuffer method, RustBuffer data +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_PUBKYUNAUTHENTICATEDTRANSPORT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CLONE_PUBKYUNAUTHENTICATEDTRANSPORT +void*_Nonnull uniffi_bitkitcore_fn_clone_pubkyunauthenticatedtransport(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FREE_PUBKYUNAUTHENTICATEDTRANSPORT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FREE_PUBKYUNAUTHENTICATEDTRANSPORT +void uniffi_bitkitcore_fn_free_pubkyunauthenticatedtransport(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CONSTRUCTOR_PUBKYUNAUTHENTICATEDTRANSPORT_NEW +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_CONSTRUCTOR_PUBKYUNAUTHENTICATEDTRANSPORT_NEW +void*_Nonnull uniffi_bitkitcore_fn_constructor_pubkyunauthenticatedtransport_new(RustCallStatus *_Nonnull out_status + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_KNOWN_CONTACTS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_KNOWN_CONTACTS +uint64_t uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_known_contacts(void*_Nonnull ptr, RustBuffer key +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_endpoint(void*_Nonnull ptr, RustBuffer payee, RustBuffer method +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_LIST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_LIST +uint64_t uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_list(void*_Nonnull ptr, RustBuffer payee +); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_ACTIVITY_WIPE_ALL #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_ACTIVITY_WIPE_ALL @@ -305,11 +362,26 @@ RustBuffer uniffi_bitkitcore_fn_func_create_channel_request_url(RustBuffer k1, R uint64_t uniffi_bitkitcore_fn_func_create_cjit_entry(uint64_t channel_size_sat, uint64_t invoice_sat, RustBuffer invoice_description, RustBuffer node_id, uint32_t channel_expiry_weeks, RustBuffer options ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_DEEPLINK_FROM_TOKEN +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_DEEPLINK_FROM_TOKEN +RustBuffer uniffi_bitkitcore_fn_func_create_deeplink_from_token(RustBuffer base_url, RustBuffer action, RustBuffer token, RustBuffer additional_params, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_ORDER #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_ORDER uint64_t uniffi_bitkitcore_fn_func_create_order(uint64_t lsp_balance_sat, uint32_t channel_expiry_weeks, RustBuffer options ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_PUBKY_RING_SESSION_REQUEST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_PUBKY_RING_SESSION_REQUEST +RustBuffer uniffi_bitkitcore_fn_func_create_pubky_ring_session_request(RustBuffer callback_url, RustBuffer additional_params, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_SESSION_TOKEN_FROM_KEYPAIR +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_SESSION_TOKEN_FROM_KEYPAIR +RustBuffer uniffi_bitkitcore_fn_func_create_session_token_from_keypair(RustBuffer public_key, RustBuffer secret_key, RustBuffer homeserver_url, RustBuffer expires_in_seconds, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_WITHDRAW_CALLBACK_URL #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_CREATE_WITHDRAW_CALLBACK_URL RustBuffer uniffi_bitkitcore_fn_func_create_withdraw_callback_url(RustBuffer k1, RustBuffer callback, RustBuffer payment_request, RustCallStatus *_Nonnull out_status @@ -345,6 +417,11 @@ RustBuffer uniffi_bitkitcore_fn_func_derive_bitcoin_addresses(RustBuffer mnemoni RustBuffer uniffi_bitkitcore_fn_func_derive_private_key(RustBuffer mnemonic_phrase, RustBuffer derivation_path_str, RustBuffer network, RustBuffer bip39_passphrase, RustCallStatus *_Nonnull out_status ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_DESERIALIZE_TOKEN_TO_SESSION +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_DESERIALIZE_TOKEN_TO_SESSION +RustBuffer uniffi_bitkitcore_fn_func_deserialize_token_to_session(RustBuffer token, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_ENTROPY_TO_MNEMONIC #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_ENTROPY_TO_MNEMONIC RustBuffer uniffi_bitkitcore_fn_func_entropy_to_mnemonic(RustBuffer entropy, RustCallStatus *_Nonnull out_status @@ -444,6 +521,11 @@ uint64_t uniffi_bitkitcore_fn_func_get_gift(RustBuffer gift_id uint64_t uniffi_bitkitcore_fn_func_get_info(RustBuffer refresh ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_KNOWN_CONTACTS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_KNOWN_CONTACTS +uint64_t uniffi_bitkitcore_fn_func_get_known_contacts(void*_Nonnull reader, RustBuffer key +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_LNURL_INVOICE #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_LNURL_INVOICE uint64_t uniffi_bitkitcore_fn_func_get_lnurl_invoice(RustBuffer address, uint64_t amount_satoshis @@ -464,6 +546,16 @@ uint64_t uniffi_bitkitcore_fn_func_get_orders(RustBuffer order_ids, RustBuffer f uint64_t uniffi_bitkitcore_fn_func_get_payment(RustBuffer payment_id ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_func_get_payment_endpoint(void*_Nonnull reader, RustBuffer payee, RustBuffer method +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PAYMENT_LIST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PAYMENT_LIST +uint64_t uniffi_bitkitcore_fn_func_get_payment_list(void*_Nonnull reader, RustBuffer payee +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PRE_ACTIVITY_METADATA #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_GET_PRE_ACTIVITY_METADATA RustBuffer uniffi_bitkitcore_fn_func_get_pre_activity_metadata(RustBuffer search_key, int8_t search_by_address, RustCallStatus *_Nonnull out_status @@ -524,6 +616,11 @@ RustBuffer uniffi_bitkitcore_fn_func_mnemonic_to_seed(RustBuffer mnemonic_phrase uint64_t uniffi_bitkitcore_fn_func_open_channel(RustBuffer order_id, RustBuffer connection_string ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_PARSE_PAYKIT_DEEPLINK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_PARSE_PAYKIT_DEEPLINK +RustBuffer uniffi_bitkitcore_fn_func_parse_paykit_deeplink(RustBuffer url, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REFRESH_ACTIVE_CJIT_ENTRIES #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REFRESH_ACTIVE_CJIT_ENTRIES uint64_t uniffi_bitkitcore_fn_func_refresh_active_cjit_entries(void @@ -571,6 +668,11 @@ uint64_t uniffi_bitkitcore_fn_func_regtest_pay(RustBuffer invoice, RustBuffer am int8_t uniffi_bitkitcore_fn_func_remove_closed_channel_by_id(RustBuffer channel_id, RustCallStatus *_Nonnull out_status ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REMOVE_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REMOVE_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_func_remove_payment_endpoint(void*_Nonnull client, RustBuffer method +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REMOVE_PRE_ACTIVITY_METADATA_TAGS #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REMOVE_PRE_ACTIVITY_METADATA_TAGS void uniffi_bitkitcore_fn_func_remove_pre_activity_metadata_tags(RustBuffer payment_id, RustBuffer tags, RustCallStatus *_Nonnull out_status @@ -586,6 +688,16 @@ void uniffi_bitkitcore_fn_func_remove_tags(RustBuffer activity_id, RustBuffer ta void uniffi_bitkitcore_fn_func_reset_pre_activity_metadata_tags(RustBuffer payment_id, RustCallStatus *_Nonnull out_status ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_SERIALIZE_SESSION_TO_TOKEN +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_SERIALIZE_SESSION_TO_TOKEN +RustBuffer uniffi_bitkitcore_fn_func_serialize_session_to_token(RustBuffer session_data, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_SET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_SET_PAYMENT_ENDPOINT +uint64_t uniffi_bitkitcore_fn_func_set_payment_endpoint(void*_Nonnull client, RustBuffer method, RustBuffer data +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_TEST_NOTIFICATION #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_TEST_NOTIFICATION uint64_t uniffi_bitkitcore_fn_func_test_notification(RustBuffer device_token, RustBuffer secret_message, RustBuffer notification_type, RustBuffer custom_url @@ -706,6 +818,11 @@ RustBuffer uniffi_bitkitcore_fn_func_validate_bitcoin_address(RustBuffer address void uniffi_bitkitcore_fn_func_validate_mnemonic(RustBuffer mnemonic_phrase, RustCallStatus *_Nonnull out_status ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_VALIDATE_PAYKIT_DEEPLINK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_VALIDATE_PAYKIT_DEEPLINK +int8_t uniffi_bitkitcore_fn_func_validate_paykit_deeplink(RustBuffer url, RustCallStatus *_Nonnull out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_WIPE_ALL_CLOSED_CHANNELS #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_WIPE_ALL_CLOSED_CHANNELS void uniffi_bitkitcore_fn_func_wipe_all_closed_channels(RustCallStatus *_Nonnull out_status @@ -1056,12 +1173,30 @@ uint16_t uniffi_bitkitcore_checksum_func_create_channel_request_url(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_CJIT_ENTRY uint16_t uniffi_bitkitcore_checksum_func_create_cjit_entry(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_DEEPLINK_FROM_TOKEN +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_DEEPLINK_FROM_TOKEN +uint16_t uniffi_bitkitcore_checksum_func_create_deeplink_from_token(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_ORDER #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_ORDER uint16_t uniffi_bitkitcore_checksum_func_create_order(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_PUBKY_RING_SESSION_REQUEST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_PUBKY_RING_SESSION_REQUEST +uint16_t uniffi_bitkitcore_checksum_func_create_pubky_ring_session_request(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_SESSION_TOKEN_FROM_KEYPAIR +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_SESSION_TOKEN_FROM_KEYPAIR +uint16_t uniffi_bitkitcore_checksum_func_create_session_token_from_keypair(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_CREATE_WITHDRAW_CALLBACK_URL @@ -1104,6 +1239,12 @@ uint16_t uniffi_bitkitcore_checksum_func_derive_bitcoin_addresses(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_DERIVE_PRIVATE_KEY uint16_t uniffi_bitkitcore_checksum_func_derive_private_key(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_DESERIALIZE_TOKEN_TO_SESSION +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_DESERIALIZE_TOKEN_TO_SESSION +uint16_t uniffi_bitkitcore_checksum_func_deserialize_token_to_session(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_ENTROPY_TO_MNEMONIC @@ -1218,6 +1359,12 @@ uint16_t uniffi_bitkitcore_checksum_func_get_gift(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_INFO uint16_t uniffi_bitkitcore_checksum_func_get_info(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_KNOWN_CONTACTS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_KNOWN_CONTACTS +uint16_t uniffi_bitkitcore_checksum_func_get_known_contacts(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_LNURL_INVOICE @@ -1242,6 +1389,18 @@ uint16_t uniffi_bitkitcore_checksum_func_get_orders(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PAYMENT uint16_t uniffi_bitkitcore_checksum_func_get_payment(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_func_get_payment_endpoint(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PAYMENT_LIST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PAYMENT_LIST +uint16_t uniffi_bitkitcore_checksum_func_get_payment_list(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_GET_PRE_ACTIVITY_METADATA @@ -1314,6 +1473,12 @@ uint16_t uniffi_bitkitcore_checksum_func_mnemonic_to_seed(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_OPEN_CHANNEL uint16_t uniffi_bitkitcore_checksum_func_open_channel(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_PARSE_PAYKIT_DEEPLINK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_PARSE_PAYKIT_DEEPLINK +uint16_t uniffi_bitkitcore_checksum_func_parse_paykit_deeplink(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REFRESH_ACTIVE_CJIT_ENTRIES @@ -1368,6 +1533,12 @@ uint16_t uniffi_bitkitcore_checksum_func_regtest_pay(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REMOVE_CLOSED_CHANNEL_BY_ID uint16_t uniffi_bitkitcore_checksum_func_remove_closed_channel_by_id(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REMOVE_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REMOVE_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_func_remove_payment_endpoint(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REMOVE_PRE_ACTIVITY_METADATA_TAGS @@ -1386,6 +1557,18 @@ uint16_t uniffi_bitkitcore_checksum_func_remove_tags(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_RESET_PRE_ACTIVITY_METADATA_TAGS uint16_t uniffi_bitkitcore_checksum_func_reset_pre_activity_metadata_tags(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_SERIALIZE_SESSION_TO_TOKEN +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_SERIALIZE_SESSION_TO_TOKEN +uint16_t uniffi_bitkitcore_checksum_func_serialize_session_to_token(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_SET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_SET_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_func_set_payment_endpoint(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_TEST_NOTIFICATION @@ -1530,6 +1713,12 @@ uint16_t uniffi_bitkitcore_checksum_func_validate_bitcoin_address(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_VALIDATE_MNEMONIC uint16_t uniffi_bitkitcore_checksum_func_validate_mnemonic(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_VALIDATE_PAYKIT_DEEPLINK +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_VALIDATE_PAYKIT_DEEPLINK +uint16_t uniffi_bitkitcore_checksum_func_validate_paykit_deeplink(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_WIPE_ALL_CLOSED_CHANNELS @@ -1542,6 +1731,48 @@ uint16_t uniffi_bitkitcore_checksum_func_wipe_all_closed_channels(void #define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_WIPE_ALL_DATABASES uint16_t uniffi_bitkitcore_checksum_func_wipe_all_databases(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYAUTHENTICATEDTRANSPORT_REMOVE_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYAUTHENTICATEDTRANSPORT_REMOVE_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_remove_payment_endpoint(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYAUTHENTICATEDTRANSPORT_SET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYAUTHENTICATEDTRANSPORT_SET_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_set_payment_endpoint(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_KNOWN_CONTACTS +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_KNOWN_CONTACTS +uint16_t uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_known_contacts(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_ENDPOINT +uint16_t uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_endpoint(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_LIST +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_METHOD_PUBKYUNAUTHENTICATEDTRANSPORT_GET_PAYMENT_LIST +uint16_t uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_list(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_CONSTRUCTOR_PUBKYAUTHENTICATEDTRANSPORT_NEW +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_CONSTRUCTOR_PUBKYAUTHENTICATEDTRANSPORT_NEW +uint16_t uniffi_bitkitcore_checksum_constructor_pubkyauthenticatedtransport_new(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_CONSTRUCTOR_PUBKYUNAUTHENTICATEDTRANSPORT_NEW +#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_CONSTRUCTOR_PUBKYUNAUTHENTICATEDTRANSPORT_NEW +uint16_t uniffi_bitkitcore_checksum_constructor_pubkyunauthenticatedtransport_new(void + ); #endif #ifndef UNIFFI_FFIDEF_FFI_BITKITCORE_UNIFFI_CONTRACT_VERSION diff --git a/bindings/python/bitkitcore/bitkitcore.py b/bindings/python/bitkitcore/bitkitcore.py index 2aaef2a..a1bd0c2 100644 --- a/bindings/python/bitkitcore/bitkitcore.py +++ b/bindings/python/bitkitcore/bitkitcore.py @@ -481,8 +481,14 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_create_cjit_entry() != 51504: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_func_create_deeplink_from_token() != 51091: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_create_order() != 33461: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_func_create_pubky_ring_session_request() != 2842: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_func_create_session_token_from_keypair() != 61582: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_create_withdraw_callback_url() != 39350: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_decode() != 28437: @@ -497,6 +503,8 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_derive_private_key() != 25155: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_func_deserialize_token_to_session() != 9427: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_entropy_to_mnemonic() != 26123: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_estimate_order_fee() != 9548: @@ -535,6 +543,8 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_get_info() != 43607: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_func_get_known_contacts() != 14867: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_get_lnurl_invoice() != 5475: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_get_min_zero_conf_tx_fee() != 6427: @@ -543,6 +553,10 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_get_payment() != 29170: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_func_get_payment_endpoint() != 60834: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_func_get_payment_list() != 49866: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_get_pre_activity_metadata() != 53126: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_get_tags() != 11308: @@ -567,6 +581,8 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_open_channel() != 21402: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_func_parse_paykit_deeplink() != 40846: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_refresh_active_cjit_entries() != 5324: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_refresh_active_orders() != 50661: @@ -585,12 +601,18 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_remove_closed_channel_by_id() != 17150: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_func_remove_payment_endpoint() != 692: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_remove_pre_activity_metadata_tags() != 1991: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_remove_tags() != 58873: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_reset_pre_activity_metadata_tags() != 34703: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_func_serialize_session_to_token() != 52557: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_func_set_payment_endpoint() != 19775: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_test_notification() != 32857: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_trezor_compose_transaction() != 25990: @@ -639,10 +661,26 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_validate_mnemonic() != 31005: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_func_validate_paykit_deeplink() != 64617: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_wipe_all_closed_channels() != 41511: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_bitkitcore_checksum_func_wipe_all_databases() != 54605: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_remove_payment_endpoint() != 6181: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_set_payment_endpoint() != 9801: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_known_contacts() != 59528: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_endpoint() != 53072: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_list() != 50101: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_constructor_pubkyauthenticatedtransport_new() != 38771: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_bitkitcore_checksum_constructor_pubkyunauthenticatedtransport_new() != 43061: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") # A ctypes library to expose the extern-C FFI definitions. # This is an implementation detail which will be called internally by the public API. @@ -749,6 +787,61 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ] _UNIFFI_FOREIGN_FUTURE_COMPLETE_VOID = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiForeignFutureStructVoid, ) +_UniffiLib.uniffi_bitkitcore_fn_clone_pubkyauthenticatedtransport.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_bitkitcore_fn_clone_pubkyauthenticatedtransport.restype = ctypes.c_void_p +_UniffiLib.uniffi_bitkitcore_fn_free_pubkyauthenticatedtransport.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_bitkitcore_fn_free_pubkyauthenticatedtransport.restype = None +_UniffiLib.uniffi_bitkitcore_fn_constructor_pubkyauthenticatedtransport_new.argtypes = ( + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_bitkitcore_fn_constructor_pubkyauthenticatedtransport_new.restype = ctypes.c_void_p +_UniffiLib.uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_remove_payment_endpoint.argtypes = ( + ctypes.c_void_p, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_remove_payment_endpoint.restype = ctypes.c_uint64 +_UniffiLib.uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_set_payment_endpoint.argtypes = ( + ctypes.c_void_p, + _UniffiRustBuffer, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_set_payment_endpoint.restype = ctypes.c_uint64 +_UniffiLib.uniffi_bitkitcore_fn_clone_pubkyunauthenticatedtransport.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_bitkitcore_fn_clone_pubkyunauthenticatedtransport.restype = ctypes.c_void_p +_UniffiLib.uniffi_bitkitcore_fn_free_pubkyunauthenticatedtransport.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_bitkitcore_fn_free_pubkyunauthenticatedtransport.restype = None +_UniffiLib.uniffi_bitkitcore_fn_constructor_pubkyunauthenticatedtransport_new.argtypes = ( + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_bitkitcore_fn_constructor_pubkyunauthenticatedtransport_new.restype = ctypes.c_void_p +_UniffiLib.uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_known_contacts.argtypes = ( + ctypes.c_void_p, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_known_contacts.restype = ctypes.c_uint64 +_UniffiLib.uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_endpoint.argtypes = ( + ctypes.c_void_p, + _UniffiRustBuffer, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_endpoint.restype = ctypes.c_uint64 +_UniffiLib.uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_list.argtypes = ( + ctypes.c_void_p, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_list.restype = ctypes.c_uint64 _UniffiLib.uniffi_bitkitcore_fn_func_activity_wipe_all.argtypes = ( ctypes.POINTER(_UniffiRustCallStatus), ) @@ -802,12 +895,34 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiRustBuffer, ) _UniffiLib.uniffi_bitkitcore_fn_func_create_cjit_entry.restype = ctypes.c_uint64 +_UniffiLib.uniffi_bitkitcore_fn_func_create_deeplink_from_token.argtypes = ( + _UniffiRustBuffer, + _UniffiRustBuffer, + _UniffiRustBuffer, + _UniffiRustBuffer, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_bitkitcore_fn_func_create_deeplink_from_token.restype = _UniffiRustBuffer _UniffiLib.uniffi_bitkitcore_fn_func_create_order.argtypes = ( ctypes.c_uint64, ctypes.c_uint32, _UniffiRustBuffer, ) _UniffiLib.uniffi_bitkitcore_fn_func_create_order.restype = ctypes.c_uint64 +_UniffiLib.uniffi_bitkitcore_fn_func_create_pubky_ring_session_request.argtypes = ( + _UniffiRustBuffer, + _UniffiRustBuffer, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_bitkitcore_fn_func_create_pubky_ring_session_request.restype = _UniffiRustBuffer +_UniffiLib.uniffi_bitkitcore_fn_func_create_session_token_from_keypair.argtypes = ( + _UniffiRustBuffer, + _UniffiRustBuffer, + _UniffiRustBuffer, + _UniffiRustBuffer, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_bitkitcore_fn_func_create_session_token_from_keypair.restype = _UniffiRustBuffer _UniffiLib.uniffi_bitkitcore_fn_func_create_withdraw_callback_url.argtypes = ( _UniffiRustBuffer, _UniffiRustBuffer, @@ -856,6 +971,11 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_bitkitcore_fn_func_derive_private_key.restype = _UniffiRustBuffer +_UniffiLib.uniffi_bitkitcore_fn_func_deserialize_token_to_session.argtypes = ( + _UniffiRustBuffer, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_bitkitcore_fn_func_deserialize_token_to_session.restype = _UniffiRustBuffer _UniffiLib.uniffi_bitkitcore_fn_func_entropy_to_mnemonic.argtypes = ( _UniffiRustBuffer, ctypes.POINTER(_UniffiRustCallStatus), @@ -958,6 +1078,11 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiRustBuffer, ) _UniffiLib.uniffi_bitkitcore_fn_func_get_info.restype = ctypes.c_uint64 +_UniffiLib.uniffi_bitkitcore_fn_func_get_known_contacts.argtypes = ( + ctypes.c_void_p, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_bitkitcore_fn_func_get_known_contacts.restype = ctypes.c_uint64 _UniffiLib.uniffi_bitkitcore_fn_func_get_lnurl_invoice.argtypes = ( _UniffiRustBuffer, ctypes.c_uint64, @@ -977,6 +1102,17 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiRustBuffer, ) _UniffiLib.uniffi_bitkitcore_fn_func_get_payment.restype = ctypes.c_uint64 +_UniffiLib.uniffi_bitkitcore_fn_func_get_payment_endpoint.argtypes = ( + ctypes.c_void_p, + _UniffiRustBuffer, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_bitkitcore_fn_func_get_payment_endpoint.restype = ctypes.c_uint64 +_UniffiLib.uniffi_bitkitcore_fn_func_get_payment_list.argtypes = ( + ctypes.c_void_p, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_bitkitcore_fn_func_get_payment_list.restype = ctypes.c_uint64 _UniffiLib.uniffi_bitkitcore_fn_func_get_pre_activity_metadata.argtypes = ( _UniffiRustBuffer, ctypes.c_int8, @@ -1042,6 +1178,11 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiRustBuffer, ) _UniffiLib.uniffi_bitkitcore_fn_func_open_channel.restype = ctypes.c_uint64 +_UniffiLib.uniffi_bitkitcore_fn_func_parse_paykit_deeplink.argtypes = ( + _UniffiRustBuffer, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_bitkitcore_fn_func_parse_paykit_deeplink.restype = _UniffiRustBuffer _UniffiLib.uniffi_bitkitcore_fn_func_refresh_active_cjit_entries.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_fn_func_refresh_active_cjit_entries.restype = ctypes.c_uint64 @@ -1088,6 +1229,11 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_bitkitcore_fn_func_remove_closed_channel_by_id.restype = ctypes.c_int8 +_UniffiLib.uniffi_bitkitcore_fn_func_remove_payment_endpoint.argtypes = ( + ctypes.c_void_p, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_bitkitcore_fn_func_remove_payment_endpoint.restype = ctypes.c_uint64 _UniffiLib.uniffi_bitkitcore_fn_func_remove_pre_activity_metadata_tags.argtypes = ( _UniffiRustBuffer, _UniffiRustBuffer, @@ -1105,6 +1251,17 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_bitkitcore_fn_func_reset_pre_activity_metadata_tags.restype = None +_UniffiLib.uniffi_bitkitcore_fn_func_serialize_session_to_token.argtypes = ( + _UniffiRustBuffer, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_bitkitcore_fn_func_serialize_session_to_token.restype = _UniffiRustBuffer +_UniffiLib.uniffi_bitkitcore_fn_func_set_payment_endpoint.argtypes = ( + ctypes.c_void_p, + _UniffiRustBuffer, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_bitkitcore_fn_func_set_payment_endpoint.restype = ctypes.c_uint64 _UniffiLib.uniffi_bitkitcore_fn_func_test_notification.argtypes = ( _UniffiRustBuffer, _UniffiRustBuffer, @@ -1302,6 +1459,11 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_bitkitcore_fn_func_validate_mnemonic.restype = None +_UniffiLib.uniffi_bitkitcore_fn_func_validate_paykit_deeplink.argtypes = ( + _UniffiRustBuffer, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_bitkitcore_fn_func_validate_paykit_deeplink.restype = ctypes.c_int8 _UniffiLib.uniffi_bitkitcore_fn_func_wipe_all_closed_channels.argtypes = ( ctypes.POINTER(_UniffiRustCallStatus), ) @@ -1607,9 +1769,18 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiLib.uniffi_bitkitcore_checksum_func_create_cjit_entry.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_create_cjit_entry.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_func_create_deeplink_from_token.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_func_create_deeplink_from_token.restype = ctypes.c_uint16 _UniffiLib.uniffi_bitkitcore_checksum_func_create_order.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_create_order.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_func_create_pubky_ring_session_request.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_func_create_pubky_ring_session_request.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_func_create_session_token_from_keypair.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_func_create_session_token_from_keypair.restype = ctypes.c_uint16 _UniffiLib.uniffi_bitkitcore_checksum_func_create_withdraw_callback_url.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_create_withdraw_callback_url.restype = ctypes.c_uint16 @@ -1631,6 +1802,9 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiLib.uniffi_bitkitcore_checksum_func_derive_private_key.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_derive_private_key.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_func_deserialize_token_to_session.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_func_deserialize_token_to_session.restype = ctypes.c_uint16 _UniffiLib.uniffi_bitkitcore_checksum_func_entropy_to_mnemonic.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_entropy_to_mnemonic.restype = ctypes.c_uint16 @@ -1688,6 +1862,9 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiLib.uniffi_bitkitcore_checksum_func_get_info.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_get_info.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_func_get_known_contacts.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_func_get_known_contacts.restype = ctypes.c_uint16 _UniffiLib.uniffi_bitkitcore_checksum_func_get_lnurl_invoice.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_get_lnurl_invoice.restype = ctypes.c_uint16 @@ -1700,6 +1877,12 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiLib.uniffi_bitkitcore_checksum_func_get_payment.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_get_payment.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_func_get_payment_endpoint.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_func_get_payment_endpoint.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_func_get_payment_list.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_func_get_payment_list.restype = ctypes.c_uint16 _UniffiLib.uniffi_bitkitcore_checksum_func_get_pre_activity_metadata.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_get_pre_activity_metadata.restype = ctypes.c_uint16 @@ -1736,6 +1919,9 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiLib.uniffi_bitkitcore_checksum_func_open_channel.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_open_channel.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_func_parse_paykit_deeplink.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_func_parse_paykit_deeplink.restype = ctypes.c_uint16 _UniffiLib.uniffi_bitkitcore_checksum_func_refresh_active_cjit_entries.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_refresh_active_cjit_entries.restype = ctypes.c_uint16 @@ -1763,6 +1949,9 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiLib.uniffi_bitkitcore_checksum_func_remove_closed_channel_by_id.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_remove_closed_channel_by_id.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_func_remove_payment_endpoint.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_func_remove_payment_endpoint.restype = ctypes.c_uint16 _UniffiLib.uniffi_bitkitcore_checksum_func_remove_pre_activity_metadata_tags.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_remove_pre_activity_metadata_tags.restype = ctypes.c_uint16 @@ -1772,6 +1961,12 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiLib.uniffi_bitkitcore_checksum_func_reset_pre_activity_metadata_tags.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_reset_pre_activity_metadata_tags.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_func_serialize_session_to_token.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_func_serialize_session_to_token.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_func_set_payment_endpoint.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_func_set_payment_endpoint.restype = ctypes.c_uint16 _UniffiLib.uniffi_bitkitcore_checksum_func_test_notification.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_test_notification.restype = ctypes.c_uint16 @@ -1844,12 +2039,36 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiLib.uniffi_bitkitcore_checksum_func_validate_mnemonic.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_validate_mnemonic.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_func_validate_paykit_deeplink.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_func_validate_paykit_deeplink.restype = ctypes.c_uint16 _UniffiLib.uniffi_bitkitcore_checksum_func_wipe_all_closed_channels.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_wipe_all_closed_channels.restype = ctypes.c_uint16 _UniffiLib.uniffi_bitkitcore_checksum_func_wipe_all_databases.argtypes = ( ) _UniffiLib.uniffi_bitkitcore_checksum_func_wipe_all_databases.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_remove_payment_endpoint.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_remove_payment_endpoint.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_set_payment_endpoint.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_method_pubkyauthenticatedtransport_set_payment_endpoint.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_known_contacts.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_known_contacts.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_endpoint.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_endpoint.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_list.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_method_pubkyunauthenticatedtransport_get_payment_list.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_constructor_pubkyauthenticatedtransport_new.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_constructor_pubkyauthenticatedtransport_new.restype = ctypes.c_uint16 +_UniffiLib.uniffi_bitkitcore_checksum_constructor_pubkyunauthenticatedtransport_new.argtypes = ( +) +_UniffiLib.uniffi_bitkitcore_checksum_constructor_pubkyunauthenticatedtransport_new.restype = ctypes.c_uint16 _UniffiLib.ffi_bitkitcore_uniffi_contract_version.argtypes = ( ) _UniffiLib.ffi_bitkitcore_uniffi_contract_version.restype = ctypes.c_uint32 @@ -1899,6 +2118,19 @@ def read(buf): def write(value, buf): buf.write_u64(value) +class _UniffiConverterInt64(_UniffiConverterPrimitiveInt): + CLASS_NAME = "i64" + VALUE_MIN = -2**63 + VALUE_MAX = 2**63 + + @staticmethod + def read(buf): + return buf.read_i64() + + @staticmethod + def write(value, buf): + buf.write_i64(value) + class _UniffiConverterDouble(_UniffiConverterPrimitiveFloat): @staticmethod def read(buf): @@ -1982,6 +2214,10 @@ def write(value, buf): buf.write(value) + + + + class AccountAddresses: """ Account addresses @@ -3068,6 +3304,39 @@ def write(value, buf): _UniffiConverterOptionalUInt32.write(value.instance, buf) +class EndpointData: + """ + Serialized payload served by a payment endpoint (UTF-8 text such as JSON, LNURL, etc.). + """ + + data: "str" + def __init__(self, *, data: "str"): + self.data = data + + def __str__(self): + return "EndpointData(data={})".format(self.data) + + def __eq__(self, other): + if self.data != other.data: + return False + return True + +class _UniffiConverterTypeEndpointData(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return EndpointData( + data=_UniffiConverterString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterString.check_lower(value.data) + + @staticmethod + def write(value, buf): + _UniffiConverterString.write(value.data, buf) + + class ErrorData: error_details: "str" def __init__(self, *, error_details: "str"): @@ -6016,6 +6285,39 @@ def write(value, buf): _UniffiConverterString.write(value.signature, buf) +class MethodId: + """ + Identifier for a payment method specification (e.g., "lightning", "onchain", "bolt11"). + """ + + id: "str" + def __init__(self, *, id: "str"): + self.id = id + + def __str__(self): + return "MethodId(id={})".format(self.id) + + def __eq__(self, other): + if self.id != other.id: + return False + return True + +class _UniffiConverterTypeMethodId(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return MethodId( + id=_UniffiConverterString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterString.check_lower(value.id) + + @staticmethod + def write(value, buf): + _UniffiConverterString.write(value.id, buf) + + class MultisigRedeemScriptType: """ Multisig Redeem Script Type @@ -6302,6 +6604,65 @@ def write(value, buf): _UniffiConverterOptionalUInt64.write(value.updated_at, buf) +class PaykitDeeplink: + """ + Represents a parsed deeplink with Paykit session information + """ + + action: "str" + """ + The action to perform (e.g., "session", "payment", "connect") + """ + + session_token: "typing.Optional[str]" + """ + The session token if present + """ + + parameters: "dict[str, str]" + """ + Additional parameters from the deeplink + """ + + def __init__(self, *, action: "str", session_token: "typing.Optional[str]", parameters: "dict[str, str]"): + self.action = action + self.session_token = session_token + self.parameters = parameters + + def __str__(self): + return "PaykitDeeplink(action={}, session_token={}, parameters={})".format(self.action, self.session_token, self.parameters) + + def __eq__(self, other): + if self.action != other.action: + return False + if self.session_token != other.session_token: + return False + if self.parameters != other.parameters: + return False + return True + +class _UniffiConverterTypePaykitDeeplink(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PaykitDeeplink( + action=_UniffiConverterString.read(buf), + session_token=_UniffiConverterOptionalString.read(buf), + parameters=_UniffiConverterMapStringString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterString.check_lower(value.action) + _UniffiConverterOptionalString.check_lower(value.session_token) + _UniffiConverterMapStringString.check_lower(value.parameters) + + @staticmethod + def write(value, buf): + _UniffiConverterString.write(value.action, buf) + _UniffiConverterOptionalString.write(value.session_token, buf) + _UniffiConverterMapStringString.write(value.parameters, buf) + + class PaymentRequestMemo: """ Payment request memo types @@ -6747,6 +7108,39 @@ def write(value, buf): _UniffiConverterString.write(value.data, buf) +class PublicKey: + """ + Public key wrapper for Paykit operations. + """ + + key: "str" + def __init__(self, *, key: "str"): + self.key = key + + def __str__(self): + return "PublicKey(key={})".format(self.key) + + def __eq__(self, other): + if self.key != other.key: + return False + return True + +class _UniffiConverterTypePublicKey(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PublicKey( + key=_UniffiConverterString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterString.check_lower(value.key) + + @staticmethod + def write(value, buf): + _UniffiConverterString.write(value.key, buf) + + class PublicKeyResponse: """ Public key response containing the derived public key information @@ -7156,48 +7550,216 @@ def write(value, buf): _UniffiConverterString.write(value.mac, buf) -class SignedTransactionResponse: - """ - Signed transaction response - """ - - signatures: "typing.List[str]" - """ - Array of signer signatures - """ - - serialized_tx: "str" - """ - Serialized transaction - """ - - txid: "typing.Optional[str]" - """ - Broadcasted transaction ID (if push was true) - """ - - def __init__(self, *, signatures: "typing.List[str]", serialized_tx: "str", txid: "typing.Optional[str]"): - self.signatures = signatures - self.serialized_tx = serialized_tx - self.txid = txid +class ScannedPaykitSession: + url: "str" + action: "str" + token: "str" + parameters: "dict[str, str]" + def __init__(self, *, url: "str", action: "str", token: "str", parameters: "dict[str, str]"): + self.url = url + self.action = action + self.token = token + self.parameters = parameters def __str__(self): - return "SignedTransactionResponse(signatures={}, serialized_tx={}, txid={})".format(self.signatures, self.serialized_tx, self.txid) + return "ScannedPaykitSession(url={}, action={}, token={}, parameters={})".format(self.url, self.action, self.token, self.parameters) def __eq__(self, other): - if self.signatures != other.signatures: + if self.url != other.url: return False - if self.serialized_tx != other.serialized_tx: + if self.action != other.action: return False - if self.txid != other.txid: + if self.token != other.token: + return False + if self.parameters != other.parameters: return False return True -class _UniffiConverterTypeSignedTransactionResponse(_UniffiConverterRustBuffer): +class _UniffiConverterTypeScannedPaykitSession(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return SignedTransactionResponse( - signatures=_UniffiConverterSequenceString.read(buf), + return ScannedPaykitSession( + url=_UniffiConverterString.read(buf), + action=_UniffiConverterString.read(buf), + token=_UniffiConverterString.read(buf), + parameters=_UniffiConverterMapStringString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterString.check_lower(value.url) + _UniffiConverterString.check_lower(value.action) + _UniffiConverterString.check_lower(value.token) + _UniffiConverterMapStringString.check_lower(value.parameters) + + @staticmethod + def write(value, buf): + _UniffiConverterString.write(value.url, buf) + _UniffiConverterString.write(value.action, buf) + _UniffiConverterString.write(value.token, buf) + _UniffiConverterMapStringString.write(value.parameters, buf) + + +class SessionData: + """ + Represents serializable session data that can be passed through a deeplink + """ + + public_key: "str" + """ + The user's public key + """ + + secret_key: "str" + """ + The user's secret key (encrypted or encoded) + """ + + homeserver_url: "typing.Optional[str]" + """ + Optional homeserver URL + """ + + expires_at: "typing.Optional[int]" + """ + Session expiry timestamp (Unix timestamp) + """ + + metadata: "typing.Optional[str]" + """ + Additional metadata + """ + + def __init__(self, *, public_key: "str", secret_key: "str", homeserver_url: "typing.Optional[str]", expires_at: "typing.Optional[int]", metadata: "typing.Optional[str]"): + self.public_key = public_key + self.secret_key = secret_key + self.homeserver_url = homeserver_url + self.expires_at = expires_at + self.metadata = metadata + + def __str__(self): + return "SessionData(public_key={}, secret_key={}, homeserver_url={}, expires_at={}, metadata={})".format(self.public_key, self.secret_key, self.homeserver_url, self.expires_at, self.metadata) + + def __eq__(self, other): + if self.public_key != other.public_key: + return False + if self.secret_key != other.secret_key: + return False + if self.homeserver_url != other.homeserver_url: + return False + if self.expires_at != other.expires_at: + return False + if self.metadata != other.metadata: + return False + return True + +class _UniffiConverterTypeSessionData(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return SessionData( + public_key=_UniffiConverterString.read(buf), + secret_key=_UniffiConverterString.read(buf), + homeserver_url=_UniffiConverterOptionalString.read(buf), + expires_at=_UniffiConverterOptionalInt64.read(buf), + metadata=_UniffiConverterOptionalString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterString.check_lower(value.public_key) + _UniffiConverterString.check_lower(value.secret_key) + _UniffiConverterOptionalString.check_lower(value.homeserver_url) + _UniffiConverterOptionalInt64.check_lower(value.expires_at) + _UniffiConverterOptionalString.check_lower(value.metadata) + + @staticmethod + def write(value, buf): + _UniffiConverterString.write(value.public_key, buf) + _UniffiConverterString.write(value.secret_key, buf) + _UniffiConverterOptionalString.write(value.homeserver_url, buf) + _UniffiConverterOptionalInt64.write(value.expires_at, buf) + _UniffiConverterOptionalString.write(value.metadata, buf) + + +class SessionToken: + """ + Represents a session token that can be passed through deeplinks + """ + + token: "str" + """ + Base64 URL-safe encoded session data + """ + + def __init__(self, *, token: "str"): + self.token = token + + def __str__(self): + return "SessionToken(token={})".format(self.token) + + def __eq__(self, other): + if self.token != other.token: + return False + return True + +class _UniffiConverterTypeSessionToken(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return SessionToken( + token=_UniffiConverterString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterString.check_lower(value.token) + + @staticmethod + def write(value, buf): + _UniffiConverterString.write(value.token, buf) + + +class SignedTransactionResponse: + """ + Signed transaction response + """ + + signatures: "typing.List[str]" + """ + Array of signer signatures + """ + + serialized_tx: "str" + """ + Serialized transaction + """ + + txid: "typing.Optional[str]" + """ + Broadcasted transaction ID (if push was true) + """ + + def __init__(self, *, signatures: "typing.List[str]", serialized_tx: "str", txid: "typing.Optional[str]"): + self.signatures = signatures + self.serialized_tx = serialized_tx + self.txid = txid + + def __str__(self): + return "SignedTransactionResponse(signatures={}, serialized_tx={}, txid={})".format(self.signatures, self.serialized_tx, self.txid) + + def __eq__(self, other): + if self.signatures != other.signatures: + return False + if self.serialized_tx != other.serialized_tx: + return False + if self.txid != other.txid: + return False + return True + +class _UniffiConverterTypeSignedTransactionResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return SignedTransactionResponse( + signatures=_UniffiConverterSequenceString.read(buf), serialized_tx=_UniffiConverterString.read(buf), txid=_UniffiConverterOptionalString.read(buf), ) @@ -7215,6 +7777,39 @@ def write(value, buf): _UniffiConverterOptionalString.write(value.txid, buf) +class SupportedPayments: + """ + Collection of supported payment entries keyed by method identifiers. + """ + + entries: "dict[str, EndpointData]" + def __init__(self, *, entries: "dict[str, EndpointData]"): + self.entries = entries + + def __str__(self): + return "SupportedPayments(entries={})".format(self.entries) + + def __eq__(self, other): + if self.entries != other.entries: + return False + return True + +class _UniffiConverterTypeSupportedPayments(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return SupportedPayments( + entries=_UniffiConverterMapStringTypeEndpointData.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterMapStringTypeEndpointData.check_lower(value.entries) + + @staticmethod + def write(value, buf): + _UniffiConverterMapStringTypeEndpointData.write(value.entries, buf) + + class TextMemo: """ Text memo @@ -10462,47 +11057,235 @@ def write(value, buf): +# PaykitError +# We want to define each variant as a nested class that's also a subclass, +# which is tricky in Python. To accomplish this we're going to create each +# class separately, then manually add the child classes to the base class's +# __dict__. All of this happens in dummy class to avoid polluting the module +# namespace. +class PaykitError(Exception): + """ + Domain-specific error type for Paykit operations. + """ + pass +_UniffiTempPaykitError = PaykitError -class PaymentState(enum.Enum): - PENDING = 0 - - SUCCEEDED = 1 - - FAILED = 2 - +class PaykitError: # type: ignore + """ + Domain-specific error type for Paykit operations. + """ + + class Unimplemented(_UniffiTempPaykitError): + def __init__(self, *values): + if len(values) != 1: + raise TypeError(f"Expected 1 arguments, found {len(values)}") + if not isinstance(values[0], str): + raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") + super().__init__(", ".join(map(repr, values))) + self._values = values + def __getitem__(self, index): + return self._values[index] -class _UniffiConverterTypePaymentState(_UniffiConverterRustBuffer): + def __repr__(self): + return "PaykitError.Unimplemented({})".format(str(self)) + _UniffiTempPaykitError.Unimplemented = Unimplemented # type: ignore + class Transport(_UniffiTempPaykitError): + def __init__(self, *values): + if len(values) != 1: + raise TypeError(f"Expected 1 arguments, found {len(values)}") + if not isinstance(values[0], str): + raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") + super().__init__(", ".join(map(repr, values))) + self._values = values + + def __getitem__(self, index): + return self._values[index] + + def __repr__(self): + return "PaykitError.Transport({})".format(str(self)) + _UniffiTempPaykitError.Transport = Transport # type: ignore + class InvalidPublicKey(_UniffiTempPaykitError): + def __init__(self, *values): + if len(values) != 1: + raise TypeError(f"Expected 1 arguments, found {len(values)}") + if not isinstance(values[0], str): + raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") + super().__init__(", ".join(map(repr, values))) + self._values = values + + def __getitem__(self, index): + return self._values[index] + + def __repr__(self): + return "PaykitError.InvalidPublicKey({})".format(str(self)) + _UniffiTempPaykitError.InvalidPublicKey = InvalidPublicKey # type: ignore + class InvalidMethodId(_UniffiTempPaykitError): + def __init__(self, *values): + if len(values) != 1: + raise TypeError(f"Expected 1 arguments, found {len(values)}") + if not isinstance(values[0], str): + raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") + super().__init__(", ".join(map(repr, values))) + self._values = values + + def __getitem__(self, index): + return self._values[index] + + def __repr__(self): + return "PaykitError.InvalidMethodId({})".format(str(self)) + _UniffiTempPaykitError.InvalidMethodId = InvalidMethodId # type: ignore + class InvalidEndpointData(_UniffiTempPaykitError): + def __init__(self, *values): + if len(values) != 1: + raise TypeError(f"Expected 1 arguments, found {len(values)}") + if not isinstance(values[0], str): + raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") + super().__init__(", ".join(map(repr, values))) + self._values = values + + def __getitem__(self, index): + return self._values[index] + + def __repr__(self): + return "PaykitError.InvalidEndpointData({})".format(str(self)) + _UniffiTempPaykitError.InvalidEndpointData = InvalidEndpointData # type: ignore + class SessionError(_UniffiTempPaykitError): + def __init__(self, *values): + if len(values) != 1: + raise TypeError(f"Expected 1 arguments, found {len(values)}") + if not isinstance(values[0], str): + raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") + super().__init__(", ".join(map(repr, values))) + self._values = values + + def __getitem__(self, index): + return self._values[index] + + def __repr__(self): + return "PaykitError.SessionError({})".format(str(self)) + _UniffiTempPaykitError.SessionError = SessionError # type: ignore + +PaykitError = _UniffiTempPaykitError # type: ignore +del _UniffiTempPaykitError + + +class _UniffiConverterTypePaykitError(_UniffiConverterRustBuffer): @staticmethod def read(buf): variant = buf.read_i32() if variant == 1: - return PaymentState.PENDING + return PaykitError.Unimplemented( + _UniffiConverterString.read(buf), + ) if variant == 2: - return PaymentState.SUCCEEDED + return PaykitError.Transport( + _UniffiConverterString.read(buf), + ) if variant == 3: - return PaymentState.FAILED + return PaykitError.InvalidPublicKey( + _UniffiConverterString.read(buf), + ) + if variant == 4: + return PaykitError.InvalidMethodId( + _UniffiConverterString.read(buf), + ) + if variant == 5: + return PaykitError.InvalidEndpointData( + _UniffiConverterString.read(buf), + ) + if variant == 6: + return PaykitError.SessionError( + _UniffiConverterString.read(buf), + ) raise InternalError("Raw enum value doesn't match any cases") @staticmethod def check_lower(value): - if value == PaymentState.PENDING: + if isinstance(value, PaykitError.Unimplemented): + _UniffiConverterString.check_lower(value._values[0]) return - if value == PaymentState.SUCCEEDED: + if isinstance(value, PaykitError.Transport): + _UniffiConverterString.check_lower(value._values[0]) return - if value == PaymentState.FAILED: + if isinstance(value, PaykitError.InvalidPublicKey): + _UniffiConverterString.check_lower(value._values[0]) + return + if isinstance(value, PaykitError.InvalidMethodId): + _UniffiConverterString.check_lower(value._values[0]) + return + if isinstance(value, PaykitError.InvalidEndpointData): + _UniffiConverterString.check_lower(value._values[0]) + return + if isinstance(value, PaykitError.SessionError): + _UniffiConverterString.check_lower(value._values[0]) return - raise ValueError(value) @staticmethod def write(value, buf): - if value == PaymentState.PENDING: + if isinstance(value, PaykitError.Unimplemented): buf.write_i32(1) - if value == PaymentState.SUCCEEDED: + _UniffiConverterString.write(value._values[0], buf) + if isinstance(value, PaykitError.Transport): buf.write_i32(2) - if value == PaymentState.FAILED: + _UniffiConverterString.write(value._values[0], buf) + if isinstance(value, PaykitError.InvalidPublicKey): + buf.write_i32(3) + _UniffiConverterString.write(value._values[0], buf) + if isinstance(value, PaykitError.InvalidMethodId): + buf.write_i32(4) + _UniffiConverterString.write(value._values[0], buf) + if isinstance(value, PaykitError.InvalidEndpointData): + buf.write_i32(5) + _UniffiConverterString.write(value._values[0], buf) + if isinstance(value, PaykitError.SessionError): + buf.write_i32(6) + _UniffiConverterString.write(value._values[0], buf) + + + + + +class PaymentState(enum.Enum): + PENDING = 0 + + SUCCEEDED = 1 + + FAILED = 2 + + + +class _UniffiConverterTypePaymentState(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return PaymentState.PENDING + if variant == 2: + return PaymentState.SUCCEEDED + if variant == 3: + return PaymentState.FAILED + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == PaymentState.PENDING: + return + if value == PaymentState.SUCCEEDED: + return + if value == PaymentState.FAILED: + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value == PaymentState.PENDING: + buf.write_i32(1) + if value == PaymentState.SUCCEEDED: + buf.write_i32(2) + if value == PaymentState.FAILED: buf.write_i32(3) @@ -10602,6 +11385,22 @@ def __eq__(self, other): return False return True + class PAYKIT_SESSION: + data: "ScannedPaykitSession" + + def __init__(self,data: "ScannedPaykitSession"): + self.data = data + + def __str__(self): + return "Scanner.PAYKIT_SESSION(data={})".format(self.data) + + def __eq__(self, other): + if not other.is_PAYKIT_SESSION(): + return False + if self.data != other.data: + return False + return True + class LNURL_CHANNEL: data: "LnurlChannelData" @@ -10738,6 +11537,10 @@ def is_PUBKY_AUTH(self) -> bool: return isinstance(self, Scanner.PUBKY_AUTH) def is_pubky_auth(self) -> bool: return isinstance(self, Scanner.PUBKY_AUTH) + def is_PAYKIT_SESSION(self) -> bool: + return isinstance(self, Scanner.PAYKIT_SESSION) + def is_paykit_session(self) -> bool: + return isinstance(self, Scanner.PAYKIT_SESSION) def is_LNURL_CHANNEL(self) -> bool: return isinstance(self, Scanner.LNURL_CHANNEL) def is_lnurl_channel(self) -> bool: @@ -10774,6 +11577,7 @@ def is_gift(self) -> bool: Scanner.ON_CHAIN = type("Scanner.ON_CHAIN", (Scanner.ON_CHAIN, Scanner,), {}) # type: ignore Scanner.LIGHTNING = type("Scanner.LIGHTNING", (Scanner.LIGHTNING, Scanner,), {}) # type: ignore Scanner.PUBKY_AUTH = type("Scanner.PUBKY_AUTH", (Scanner.PUBKY_AUTH, Scanner,), {}) # type: ignore +Scanner.PAYKIT_SESSION = type("Scanner.PAYKIT_SESSION", (Scanner.PAYKIT_SESSION, Scanner,), {}) # type: ignore Scanner.LNURL_CHANNEL = type("Scanner.LNURL_CHANNEL", (Scanner.LNURL_CHANNEL, Scanner,), {}) # type: ignore Scanner.LNURL_AUTH = type("Scanner.LNURL_AUTH", (Scanner.LNURL_AUTH, Scanner,), {}) # type: ignore Scanner.LNURL_WITHDRAW = type("Scanner.LNURL_WITHDRAW", (Scanner.LNURL_WITHDRAW, Scanner,), {}) # type: ignore @@ -10802,31 +11606,35 @@ def read(buf): _UniffiConverterString.read(buf), ) if variant == 4: + return Scanner.PAYKIT_SESSION( + _UniffiConverterTypeScannedPaykitSession.read(buf), + ) + if variant == 5: return Scanner.LNURL_CHANNEL( _UniffiConverterTypeLnurlChannelData.read(buf), ) - if variant == 5: + if variant == 6: return Scanner.LNURL_AUTH( _UniffiConverterTypeLnurlAuthData.read(buf), ) - if variant == 6: + if variant == 7: return Scanner.LNURL_WITHDRAW( _UniffiConverterTypeLnurlWithdrawData.read(buf), ) - if variant == 7: + if variant == 8: return Scanner.LNURL_ADDRESS( _UniffiConverterTypeLnurlAddressData.read(buf), ) - if variant == 8: + if variant == 9: return Scanner.LNURL_PAY( _UniffiConverterTypeLnurlPayData.read(buf), ) - if variant == 9: + if variant == 10: return Scanner.NODE_ID( _UniffiConverterString.read(buf), _UniffiConverterTypeNetworkType.read(buf), ) - if variant == 10: + if variant == 11: return Scanner.GIFT( _UniffiConverterString.read(buf), _UniffiConverterUInt64.read(buf), @@ -10844,6 +11652,9 @@ def check_lower(value): if value.is_PUBKY_AUTH(): _UniffiConverterString.check_lower(value.data) return + if value.is_PAYKIT_SESSION(): + _UniffiConverterTypeScannedPaykitSession.check_lower(value.data) + return if value.is_LNURL_CHANNEL(): _UniffiConverterTypeLnurlChannelData.check_lower(value.data) return @@ -10880,27 +11691,30 @@ def write(value, buf): if value.is_PUBKY_AUTH(): buf.write_i32(3) _UniffiConverterString.write(value.data, buf) - if value.is_LNURL_CHANNEL(): + if value.is_PAYKIT_SESSION(): buf.write_i32(4) + _UniffiConverterTypeScannedPaykitSession.write(value.data, buf) + if value.is_LNURL_CHANNEL(): + buf.write_i32(5) _UniffiConverterTypeLnurlChannelData.write(value.data, buf) if value.is_LNURL_AUTH(): - buf.write_i32(5) + buf.write_i32(6) _UniffiConverterTypeLnurlAuthData.write(value.data, buf) if value.is_LNURL_WITHDRAW(): - buf.write_i32(6) + buf.write_i32(7) _UniffiConverterTypeLnurlWithdrawData.write(value.data, buf) if value.is_LNURL_ADDRESS(): - buf.write_i32(7) + buf.write_i32(8) _UniffiConverterTypeLnurlAddressData.write(value.data, buf) if value.is_LNURL_PAY(): - buf.write_i32(8) + buf.write_i32(9) _UniffiConverterTypeLnurlPayData.write(value.data, buf) if value.is_NODE_ID(): - buf.write_i32(9) + buf.write_i32(10) _UniffiConverterString.write(value.url, buf) _UniffiConverterTypeNetworkType.write(value.network, buf) if value.is_GIFT(): - buf.write_i32(10) + buf.write_i32(11) _UniffiConverterString.write(value.code, buf) _UniffiConverterUInt64.write(value.amount, buf) @@ -11838,6 +12652,33 @@ def read(cls, buf): +class _UniffiConverterOptionalInt64(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiConverterInt64.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiConverterInt64.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiConverterInt64.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + + + class _UniffiConverterOptionalBool(_UniffiConverterRustBuffer): @classmethod def check_lower(cls, value): @@ -12108,6 +12949,33 @@ def read(cls, buf): +class _UniffiConverterOptionalTypeEndpointData(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiConverterTypeEndpointData.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiConverterTypeEndpointData.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiConverterTypeEndpointData.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + + + class _UniffiConverterOptionalTypeIBtBolt11Invoice(_UniffiConverterRustBuffer): @classmethod def check_lower(cls, value): @@ -13927,6 +14795,31 @@ def read(cls, buf): +class _UniffiConverterSequenceTypePublicKey(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiConverterTypePublicKey.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiConverterTypePublicKey.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiConverterTypePublicKey.read(buf) for i in range(count) + ] + + + class _UniffiConverterSequenceTypeRefTransaction(_UniffiConverterRustBuffer): @classmethod def check_lower(cls, value): @@ -14158,7 +15051,412 @@ def read(cls, buf): d[key] = val return d + + +class _UniffiConverterMapStringTypeEndpointData(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, items): + for (key, value) in items.items(): + _UniffiConverterString.check_lower(key) + _UniffiConverterTypeEndpointData.check_lower(value) + + @classmethod + def write(cls, items, buf): + buf.write_i32(len(items)) + for (key, value) in items.items(): + _UniffiConverterString.write(key, buf) + _UniffiConverterTypeEndpointData.write(value, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative map size") + + # It would be nice to use a dict comprehension, + # but in Python 3.7 and before the evaluation order is not according to spec, + # so we we're reading the value before the key. + # This loop makes the order explicit: first reading the key, then the value. + d = {} + for i in range(count): + key = _UniffiConverterString.read(buf) + val = _UniffiConverterTypeEndpointData.read(buf) + d[key] = val + return d + # objects. +class PubkyAuthenticatedTransportProtocol(typing.Protocol): + """ + Authenticated transport wrapper for Paykit write operations. + """ + + def remove_payment_endpoint(self, method: "MethodId"): + """ + Removes a payment endpoint. + + # Parameters + - `method`: Payment method identifier to remove + + # Returns + - `Ok(())` on successful removal + - `Err` if the endpoint doesn't exist or transport fails + """ + + raise NotImplementedError + def set_payment_endpoint(self, method: "MethodId",data: "EndpointData"): + """ + Stores or updates a payment endpoint. + + # Parameters + - `method`: Payment method identifier (e.g., "lightning", "onchain") + - `data`: Endpoint data payload (UTF-8 JSON or other text format) + """ + + raise NotImplementedError +# PubkyAuthenticatedTransport is a Rust-only trait - it's a wrapper around a Rust implementation. +class PubkyAuthenticatedTransport(): + """ + Authenticated transport wrapper for Paykit write operations. + """ + + _pointer: ctypes.c_void_p + def __init__(self, ): + """ + Creates a new authenticated transport. + Note: This requires proper session initialization which should be handled + by the application layer. For now, this returns an error indicating the + need for external session management. + """ + + self._pointer = _uniffi_rust_call_with_error(_UniffiConverterTypePaykitError,_UniffiLib.uniffi_bitkitcore_fn_constructor_pubkyauthenticatedtransport_new,) + + def __del__(self): + # In case of partial initialization of instances. + pointer = getattr(self, "_pointer", None) + if pointer is not None: + _uniffi_rust_call(_UniffiLib.uniffi_bitkitcore_fn_free_pubkyauthenticatedtransport, pointer) + + def _uniffi_clone_pointer(self): + return _uniffi_rust_call(_UniffiLib.uniffi_bitkitcore_fn_clone_pubkyauthenticatedtransport, self._pointer) + + # Used by alternative constructors or any methods which return this type. + @classmethod + def _make_instance_(cls, pointer): + # Lightly yucky way to bypass the usual __init__ logic + # and just create a new instance with the required pointer. + inst = cls.__new__(cls) + inst._pointer = pointer + return inst + + async def remove_payment_endpoint(self, method: "MethodId") -> None: + + """ + Removes a payment endpoint. + + # Parameters + - `method`: Payment method identifier to remove + + # Returns + - `Ok(())` on successful removal + - `Err` if the endpoint doesn't exist or transport fails + """ + + _UniffiConverterTypeMethodId.check_lower(method) + + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_remove_payment_endpoint( + self._uniffi_clone_pointer(), + _UniffiConverterTypeMethodId.lower(method) + ), + _UniffiLib.ffi_bitkitcore_rust_future_poll_void, + _UniffiLib.ffi_bitkitcore_rust_future_complete_void, + _UniffiLib.ffi_bitkitcore_rust_future_free_void, + # lift function + lambda val: None, + + + # Error FFI converter +_UniffiConverterTypePaykitError, + + ) + + + + async def set_payment_endpoint(self, method: "MethodId",data: "EndpointData") -> None: + + """ + Stores or updates a payment endpoint. + + # Parameters + - `method`: Payment method identifier (e.g., "lightning", "onchain") + - `data`: Endpoint data payload (UTF-8 JSON or other text format) + """ + + _UniffiConverterTypeMethodId.check_lower(method) + + _UniffiConverterTypeEndpointData.check_lower(data) + + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_bitkitcore_fn_method_pubkyauthenticatedtransport_set_payment_endpoint( + self._uniffi_clone_pointer(), + _UniffiConverterTypeMethodId.lower(method), + _UniffiConverterTypeEndpointData.lower(data) + ), + _UniffiLib.ffi_bitkitcore_rust_future_poll_void, + _UniffiLib.ffi_bitkitcore_rust_future_complete_void, + _UniffiLib.ffi_bitkitcore_rust_future_free_void, + # lift function + lambda val: None, + + + # Error FFI converter +_UniffiConverterTypePaykitError, + + ) + + + + + +class _UniffiConverterTypePubkyAuthenticatedTransport: + + @staticmethod + def lift(value: int): + return PubkyAuthenticatedTransport._make_instance_(value) + + @staticmethod + def check_lower(value: PubkyAuthenticatedTransport): + if not isinstance(value, PubkyAuthenticatedTransport): + raise TypeError("Expected PubkyAuthenticatedTransport instance, {} found".format(type(value).__name__)) + + @staticmethod + def lower(value: PubkyAuthenticatedTransportProtocol): + if not isinstance(value, PubkyAuthenticatedTransport): + raise TypeError("Expected PubkyAuthenticatedTransport instance, {} found".format(type(value).__name__)) + return value._uniffi_clone_pointer() + + @classmethod + def read(cls, buf: _UniffiRustBuffer): + ptr = buf.read_u64() + if ptr == 0: + raise InternalError("Raw pointer value was null") + return cls.lift(ptr) + + @classmethod + def write(cls, value: PubkyAuthenticatedTransportProtocol, buf: _UniffiRustBuffer): + buf.write_u64(cls.lower(value)) +class PubkyUnauthenticatedTransportProtocol(typing.Protocol): + """ + Unauthenticated transport wrapper for Paykit read operations. + """ + + def get_known_contacts(self, key: "PublicKey"): + """ + Returns known contacts (follows) of a given public key. + + # Parameters + - `key`: Public key to query for contacts + + # Returns + - `Ok(Vec)` with list of known contacts + - Returns empty vector if no contacts are stored + - `Err` only on transport failures + """ + + raise NotImplementedError + def get_payment_endpoint(self, payee: "PublicKey",method: "MethodId"): + """ + Retrieves a specific payment endpoint for a payee and method. + + # Parameters + - `payee`: Public key of the payee + - `method`: Payment method identifier to query + + # Returns + - `Ok(Some(EndpointData))` if the endpoint exists + - `Ok(None)` if the endpoint is not published + - `Err` only on transport failures + """ + + raise NotImplementedError + def get_payment_list(self, payee: "PublicKey"): + """ + Retrieves all supported payment methods for a given payee. + + # Parameters + - `payee`: Public key of the payee to query + + # Returns + - `Ok(SupportedPayments)` with map of method IDs to endpoint data + - Returns empty map if no endpoints are published + - `Err` only on transport failures + """ + + raise NotImplementedError +# PubkyUnauthenticatedTransport is a Rust-only trait - it's a wrapper around a Rust implementation. +class PubkyUnauthenticatedTransport(): + """ + Unauthenticated transport wrapper for Paykit read operations. + """ + + _pointer: ctypes.c_void_p + def __init__(self, ): + """ + Creates a new unauthenticated transport for reading public payment data. + """ + + self._pointer = _uniffi_rust_call_with_error(_UniffiConverterTypePaykitError,_UniffiLib.uniffi_bitkitcore_fn_constructor_pubkyunauthenticatedtransport_new,) + + def __del__(self): + # In case of partial initialization of instances. + pointer = getattr(self, "_pointer", None) + if pointer is not None: + _uniffi_rust_call(_UniffiLib.uniffi_bitkitcore_fn_free_pubkyunauthenticatedtransport, pointer) + + def _uniffi_clone_pointer(self): + return _uniffi_rust_call(_UniffiLib.uniffi_bitkitcore_fn_clone_pubkyunauthenticatedtransport, self._pointer) + + # Used by alternative constructors or any methods which return this type. + @classmethod + def _make_instance_(cls, pointer): + # Lightly yucky way to bypass the usual __init__ logic + # and just create a new instance with the required pointer. + inst = cls.__new__(cls) + inst._pointer = pointer + return inst + + async def get_known_contacts(self, key: "PublicKey") -> "typing.List[PublicKey]": + """ + Returns known contacts (follows) of a given public key. + + # Parameters + - `key`: Public key to query for contacts + + # Returns + - `Ok(Vec)` with list of known contacts + - Returns empty vector if no contacts are stored + - `Err` only on transport failures + """ + + _UniffiConverterTypePublicKey.check_lower(key) + + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_known_contacts( + self._uniffi_clone_pointer(), + _UniffiConverterTypePublicKey.lower(key) + ), + _UniffiLib.ffi_bitkitcore_rust_future_poll_rust_buffer, + _UniffiLib.ffi_bitkitcore_rust_future_complete_rust_buffer, + _UniffiLib.ffi_bitkitcore_rust_future_free_rust_buffer, + # lift function + _UniffiConverterSequenceTypePublicKey.lift, + + # Error FFI converter +_UniffiConverterTypePaykitError, + + ) + + + + async def get_payment_endpoint(self, payee: "PublicKey",method: "MethodId") -> "typing.Optional[EndpointData]": + """ + Retrieves a specific payment endpoint for a payee and method. + + # Parameters + - `payee`: Public key of the payee + - `method`: Payment method identifier to query + + # Returns + - `Ok(Some(EndpointData))` if the endpoint exists + - `Ok(None)` if the endpoint is not published + - `Err` only on transport failures + """ + + _UniffiConverterTypePublicKey.check_lower(payee) + + _UniffiConverterTypeMethodId.check_lower(method) + + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_endpoint( + self._uniffi_clone_pointer(), + _UniffiConverterTypePublicKey.lower(payee), + _UniffiConverterTypeMethodId.lower(method) + ), + _UniffiLib.ffi_bitkitcore_rust_future_poll_rust_buffer, + _UniffiLib.ffi_bitkitcore_rust_future_complete_rust_buffer, + _UniffiLib.ffi_bitkitcore_rust_future_free_rust_buffer, + # lift function + _UniffiConverterOptionalTypeEndpointData.lift, + + # Error FFI converter +_UniffiConverterTypePaykitError, + + ) + + + + async def get_payment_list(self, payee: "PublicKey") -> "SupportedPayments": + """ + Retrieves all supported payment methods for a given payee. + + # Parameters + - `payee`: Public key of the payee to query + + # Returns + - `Ok(SupportedPayments)` with map of method IDs to endpoint data + - Returns empty map if no endpoints are published + - `Err` only on transport failures + """ + + _UniffiConverterTypePublicKey.check_lower(payee) + + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_bitkitcore_fn_method_pubkyunauthenticatedtransport_get_payment_list( + self._uniffi_clone_pointer(), + _UniffiConverterTypePublicKey.lower(payee) + ), + _UniffiLib.ffi_bitkitcore_rust_future_poll_rust_buffer, + _UniffiLib.ffi_bitkitcore_rust_future_complete_rust_buffer, + _UniffiLib.ffi_bitkitcore_rust_future_free_rust_buffer, + # lift function + _UniffiConverterTypeSupportedPayments.lift, + + # Error FFI converter +_UniffiConverterTypePaykitError, + + ) + + + + + +class _UniffiConverterTypePubkyUnauthenticatedTransport: + + @staticmethod + def lift(value: int): + return PubkyUnauthenticatedTransport._make_instance_(value) + + @staticmethod + def check_lower(value: PubkyUnauthenticatedTransport): + if not isinstance(value, PubkyUnauthenticatedTransport): + raise TypeError("Expected PubkyUnauthenticatedTransport instance, {} found".format(type(value).__name__)) + + @staticmethod + def lower(value: PubkyUnauthenticatedTransportProtocol): + if not isinstance(value, PubkyUnauthenticatedTransport): + raise TypeError("Expected PubkyUnauthenticatedTransport instance, {} found".format(type(value).__name__)) + return value._uniffi_clone_pointer() + + @classmethod + def read(cls, buf: _UniffiRustBuffer): + ptr = buf.read_u64() + if ptr == 0: + raise InternalError("Raw pointer value was null") + return cls.lift(ptr) + + @classmethod + def write(cls, value: PubkyUnauthenticatedTransportProtocol, buf: _UniffiRustBuffer): + buf.write_u64(cls.lower(value)) # Async support# RustFuturePoll values _UNIFFI_RUST_FUTURE_POLL_READY = 0 @@ -14357,6 +15655,46 @@ async def create_cjit_entry(channel_size_sat: "int",invoice_sat: "int",invoice_d _UniffiConverterTypeBlocktankError, ) + +def create_deeplink_from_token(base_url: "str",action: "str",token: "SessionToken",additional_params: "typing.Optional[dict[str, str]]") -> "str": + """ + Creates a deeplink URL from a session token. + + Use this to generate a deeplink that can be shared with another app instance. + + # Example + ``` + let token = create_session_token_from_keypair( + public_key, + secret_key, + None, + Some(3600) + )?; + + let deeplink_url = create_deeplink_from_token( + "myapp://", + "session", + token, + None + )?; + // Result: "myapp://paykit/session?token=..." + ``` + """ + + _UniffiConverterString.check_lower(base_url) + + _UniffiConverterString.check_lower(action) + + _UniffiConverterTypeSessionToken.check_lower(token) + + _UniffiConverterOptionalMapStringString.check_lower(additional_params) + + return _UniffiConverterString.lift(_uniffi_rust_call_with_error(_UniffiConverterTypePaykitError,_UniffiLib.uniffi_bitkitcore_fn_func_create_deeplink_from_token, + _UniffiConverterString.lower(base_url), + _UniffiConverterString.lower(action), + _UniffiConverterTypeSessionToken.lower(token), + _UniffiConverterOptionalMapStringString.lower(additional_params))) + async def create_order(lsp_balance_sat: "int",channel_expiry_weeks: "int",options: "typing.Optional[CreateOrderOptions]") -> "IBtOrder": _UniffiConverterUInt64.check_lower(lsp_balance_sat) @@ -14381,6 +15719,72 @@ async def create_order(lsp_balance_sat: "int",channel_expiry_weeks: "int",option ) +def create_pubky_ring_session_request(callback_url: "str",additional_params: "typing.Optional[dict[str, str]]") -> "str": + """ + Creates a session request URL to send to Pubky Ring for authentication. + + This generates a URL that Bitkit displays as a QR code or uses to open Pubky Ring. + When Pubky Ring completes authentication, it will return the session data + via the provided callback URL. + + # Parameters + - `callback_url`: The URL scheme and path where Pubky Ring should return the session. + Example: "bitkit://paykit/session-data" or "bitkit://session" + - `additional_params`: Optional additional parameters to include in the request URL + + # Returns + A URL string like: `pubkyring://session?callback=bitkit%3A%2F%2Fpaykit%2Fsession-data` + + # Example + ``` + // Generate URL for QR code or "Open Pubky Ring" button + let request_url = create_pubky_ring_session_request( + "bitkit://paykit/session-data".to_string(), + None + )?; + // Result: "pubkyring://session?callback=bitkit%3A%2F%2Fpaykit%2Fsession-data" + + // With additional parameters + let mut params = HashMap::new(); + params.insert("app_name".to_string(), "Bitkit".to_string()); + let request_url = create_pubky_ring_session_request( + "bitkit://paykit/session-data".to_string(), + Some(params) + )?; + ``` + """ + + _UniffiConverterString.check_lower(callback_url) + + _UniffiConverterOptionalMapStringString.check_lower(additional_params) + + return _UniffiConverterString.lift(_uniffi_rust_call_with_error(_UniffiConverterTypePaykitError,_UniffiLib.uniffi_bitkitcore_fn_func_create_pubky_ring_session_request, + _UniffiConverterString.lower(callback_url), + _UniffiConverterOptionalMapStringString.lower(additional_params))) + + +def create_session_token_from_keypair(public_key: "str",secret_key: "str",homeserver_url: "typing.Optional[str]",expires_in_seconds: "typing.Optional[int]") -> "SessionToken": + """ + Helper function to create a session token from raw keypair data. + + This is useful when you have the keypair but need to create a shareable token. + """ + + _UniffiConverterString.check_lower(public_key) + + _UniffiConverterString.check_lower(secret_key) + + _UniffiConverterOptionalString.check_lower(homeserver_url) + + _UniffiConverterOptionalInt64.check_lower(expires_in_seconds) + + return _UniffiConverterTypeSessionToken.lift(_uniffi_rust_call_with_error(_UniffiConverterTypePaykitError,_UniffiLib.uniffi_bitkitcore_fn_func_create_session_token_from_keypair, + _UniffiConverterString.lower(public_key), + _UniffiConverterString.lower(secret_key), + _UniffiConverterOptionalString.lower(homeserver_url), + _UniffiConverterOptionalInt64.lower(expires_in_seconds))) + + def create_withdraw_callback_url(k1: "str",callback: "str",payment_request: "str") -> "str": _UniffiConverterString.check_lower(k1) @@ -14482,6 +15886,24 @@ def derive_private_key(mnemonic_phrase: "str",derivation_path_str: "typing.Optio _UniffiConverterOptionalString.lower(bip39_passphrase))) +def deserialize_token_to_session(token: "SessionToken") -> "SessionData": + """ + Deserializes a session token back into session data. + + # Example + ``` + let token = SessionToken::new("base64_encoded_session_data"); + let session_data = deserialize_token_to_session(token)?; + // Now you have the session data back + ``` + """ + + _UniffiConverterTypeSessionToken.check_lower(token) + + return _UniffiConverterTypeSessionData.lift(_uniffi_rust_call_with_error(_UniffiConverterTypePaykitError,_UniffiLib.uniffi_bitkitcore_fn_func_deserialize_token_to_session, + _UniffiConverterTypeSessionToken.lower(token))) + + def entropy_to_mnemonic(entropy: "bytes") -> "str": _UniffiConverterBytes.check_lower(entropy) @@ -14699,6 +16121,49 @@ async def get_info(refresh: "typing.Optional[bool]") -> "typing.Optional[IBtInfo # Error FFI converter _UniffiConverterTypeBlocktankError, + ) +async def get_known_contacts(reader: "PubkyUnauthenticatedTransport",key: "PublicKey") -> "typing.List[PublicKey]": + + """ + Returns known contacts (follows) of a given public key. + + # Parameters + - `reader`: Unauthenticated transport for reading public data + - `key`: Public key to query for contacts + + # Returns + - `Ok(Vec)` with list of known contacts + - Returns empty vector if no contacts are stored + - `Err` only on transport failures + + # Example + ``` + let reader = PubkyUnauthenticatedTransport::new()?; + let user = PublicKey { key: "...".to_string() }; + let contacts = get_known_contacts(&reader, &user).await?; + for contact in contacts { + println!("Contact: {}", contact.key); + } + ``` + """ + + _UniffiConverterTypePubkyUnauthenticatedTransport.check_lower(reader) + + _UniffiConverterTypePublicKey.check_lower(key) + + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_bitkitcore_fn_func_get_known_contacts( + _UniffiConverterTypePubkyUnauthenticatedTransport.lower(reader), + _UniffiConverterTypePublicKey.lower(key)), + _UniffiLib.ffi_bitkitcore_rust_future_poll_rust_buffer, + _UniffiLib.ffi_bitkitcore_rust_future_complete_rust_buffer, + _UniffiLib.ffi_bitkitcore_rust_future_free_rust_buffer, + # lift function + _UniffiConverterSequenceTypePublicKey.lift, + + # Error FFI converter +_UniffiConverterTypePaykitError, + ) async def get_lnurl_invoice(address: "str",amount_satoshis: "int") -> "str": @@ -14777,6 +16242,96 @@ async def get_payment(payment_id: "str") -> "IBtBolt11Invoice": _UniffiConverterTypeBlocktankError, ) +async def get_payment_endpoint(reader: "PubkyUnauthenticatedTransport",payee: "PublicKey",method: "MethodId") -> "typing.Optional[EndpointData]": + + """ + Retrieves a specific payment endpoint for a payee and method. + + # Parameters + - `reader`: Unauthenticated transport for reading public data + - `payee`: Public key of the payee + - `method`: Payment method identifier to query + + # Returns + - `Ok(Some(EndpointData))` if the endpoint exists + - `Ok(None)` if the endpoint is not published + - `Err` only on transport failures + + # Example + ``` + let reader = PubkyUnauthenticatedTransport::new()?; + let payee = PublicKey { key: "...".to_string() }; + let method = MethodId { id: "lightning".to_string() }; + if let Some(endpoint) = get_payment_endpoint(&reader, &payee, &method).await? { + println!("Lightning endpoint: {}", endpoint.data); + } + ``` + """ + + _UniffiConverterTypePubkyUnauthenticatedTransport.check_lower(reader) + + _UniffiConverterTypePublicKey.check_lower(payee) + + _UniffiConverterTypeMethodId.check_lower(method) + + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_bitkitcore_fn_func_get_payment_endpoint( + _UniffiConverterTypePubkyUnauthenticatedTransport.lower(reader), + _UniffiConverterTypePublicKey.lower(payee), + _UniffiConverterTypeMethodId.lower(method)), + _UniffiLib.ffi_bitkitcore_rust_future_poll_rust_buffer, + _UniffiLib.ffi_bitkitcore_rust_future_complete_rust_buffer, + _UniffiLib.ffi_bitkitcore_rust_future_free_rust_buffer, + # lift function + _UniffiConverterOptionalTypeEndpointData.lift, + + # Error FFI converter +_UniffiConverterTypePaykitError, + + ) +async def get_payment_list(reader: "PubkyUnauthenticatedTransport",payee: "PublicKey") -> "SupportedPayments": + + """ + Retrieves all supported payment methods for a given payee. + + # Parameters + - `reader`: Unauthenticated transport for reading public data + - `payee`: Public key of the payee to query + + # Returns + - `Ok(SupportedPayments)` with map of method IDs to endpoint data + - Returns empty map if no endpoints are published + - `Err` only on transport failures + + # Example + ``` + let reader = PubkyUnauthenticatedTransport::new()?; + let payee = PublicKey { key: "...".to_string() }; + let payments = get_payment_list(&reader, &payee).await?; + for (method_id, data) in payments.entries { + println!("Method: {}, Data: {}", method_id, data.data); + } + ``` + """ + + _UniffiConverterTypePubkyUnauthenticatedTransport.check_lower(reader) + + _UniffiConverterTypePublicKey.check_lower(payee) + + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_bitkitcore_fn_func_get_payment_list( + _UniffiConverterTypePubkyUnauthenticatedTransport.lower(reader), + _UniffiConverterTypePublicKey.lower(payee)), + _UniffiLib.ffi_bitkitcore_rust_future_poll_rust_buffer, + _UniffiLib.ffi_bitkitcore_rust_future_complete_rust_buffer, + _UniffiLib.ffi_bitkitcore_rust_future_free_rust_buffer, + # lift function + _UniffiConverterTypeSupportedPayments.lift, + + # Error FFI converter +_UniffiConverterTypePaykitError, + + ) def get_pre_activity_metadata(search_key: "str",search_by_address: "bool") -> "typing.Optional[PreActivityMetadata]": _UniffiConverterString.check_lower(search_key) @@ -14928,6 +16483,30 @@ async def open_channel(order_id: "str",connection_string: "str") -> "IBtOrder": _UniffiConverterTypeBlocktankError, ) + +def parse_paykit_deeplink(url: "str") -> "PaykitDeeplink": + """ + Parses a deeplink URL into a PaykitDeeplink structure. + + # Supported URL Formats + - `myapp://paykit/session?token=` + - `myapp://paykit/connect?token=&return_url=` + - `https://myapp.com/paykit/session?token=` + + # Example + ``` + let url = "myapp://paykit/session?token=eyJwdWJsaWNfa2V5IjoiLi4uIn0"; + let deeplink = parse_paykit_deeplink(url)?; + assert_eq!(deeplink.action, "session"); + assert!(deeplink.session_token.is_some()); + ``` + """ + + _UniffiConverterString.check_lower(url) + + return _UniffiConverterTypePaykitDeeplink.lift(_uniffi_rust_call_with_error(_UniffiConverterTypePaykitError,_UniffiLib.uniffi_bitkitcore_fn_func_parse_paykit_deeplink, + _UniffiConverterString.lower(url))) + async def refresh_active_cjit_entries() -> "typing.List[IcJitEntry]": """ @@ -15107,6 +16686,39 @@ def remove_closed_channel_by_id(channel_id: "str") -> "bool": return _UniffiConverterBool.lift(_uniffi_rust_call_with_error(_UniffiConverterTypeActivityError,_UniffiLib.uniffi_bitkitcore_fn_func_remove_closed_channel_by_id, _UniffiConverterString.lower(channel_id))) +async def remove_payment_endpoint(client: "PubkyAuthenticatedTransport",method: "MethodId") -> None: + + """ + Removes a payment endpoint via the authenticated transport. + + # Parameters + - `client`: Authenticated transport client + - `method`: Payment method identifier to remove + + # Returns + - `Ok(())` on successful removal + - `Err` if the endpoint doesn't exist or transport fails + """ + + _UniffiConverterTypePubkyAuthenticatedTransport.check_lower(client) + + _UniffiConverterTypeMethodId.check_lower(method) + + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_bitkitcore_fn_func_remove_payment_endpoint( + _UniffiConverterTypePubkyAuthenticatedTransport.lower(client), + _UniffiConverterTypeMethodId.lower(method)), + _UniffiLib.ffi_bitkitcore_rust_future_poll_void, + _UniffiLib.ffi_bitkitcore_rust_future_complete_void, + _UniffiLib.ffi_bitkitcore_rust_future_free_void, + # lift function + lambda val: None, + + + # Error FFI converter +_UniffiConverterTypePaykitError, + + ) def remove_pre_activity_metadata_tags(payment_id: "str",tags: "typing.List[str]") -> None: _UniffiConverterString.check_lower(payment_id) @@ -15134,6 +16746,77 @@ def reset_pre_activity_metadata_tags(payment_id: "str") -> None: _uniffi_rust_call_with_error(_UniffiConverterTypeActivityError,_UniffiLib.uniffi_bitkitcore_fn_func_reset_pre_activity_metadata_tags, _UniffiConverterString.lower(payment_id)) + +def serialize_session_to_token(session_data: "SessionData") -> "SessionToken": + """ + Serializes session data into a token string suitable for deeplinks. + + # Security Considerations + - The secret key should be encrypted before serialization + - Use HTTPS/secure channels when transmitting + - Consider adding expiration times + - Implement token rotation for long-lived sessions + + # Example + ``` + let session_data = SessionData { + public_key: "user_public_key".to_string(), + secret_key: "encrypted_secret".to_string(), + homeserver_url: Some("https://homeserver.example".to_string()), + expires_at: Some(1234567890), + metadata: None, + }; + + let token = serialize_session_to_token(session_data)?; + // token.token can now be passed through a deeplink + ``` + """ + + _UniffiConverterTypeSessionData.check_lower(session_data) + + return _UniffiConverterTypeSessionToken.lift(_uniffi_rust_call_with_error(_UniffiConverterTypePaykitError,_UniffiLib.uniffi_bitkitcore_fn_func_serialize_session_to_token, + _UniffiConverterTypeSessionData.lower(session_data))) + +async def set_payment_endpoint(client: "PubkyAuthenticatedTransport",method: "MethodId",data: "EndpointData") -> None: + + """ + Stores or updates a payment endpoint via the authenticated transport. + + # Parameters + - `client`: Authenticated transport client + - `method`: Payment method identifier (e.g., "lightning", "onchain") + - `data`: Endpoint data payload (UTF-8 JSON or other text format) + + # Example + ``` + let method = MethodId { id: "lightning".to_string() }; + let data = EndpointData { data: r#"{"bolt11":"lnbc..."}"#.to_string() }; + set_payment_endpoint(&client, method, data).await?; + ``` + """ + + _UniffiConverterTypePubkyAuthenticatedTransport.check_lower(client) + + _UniffiConverterTypeMethodId.check_lower(method) + + _UniffiConverterTypeEndpointData.check_lower(data) + + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_bitkitcore_fn_func_set_payment_endpoint( + _UniffiConverterTypePubkyAuthenticatedTransport.lower(client), + _UniffiConverterTypeMethodId.lower(method), + _UniffiConverterTypeEndpointData.lower(data)), + _UniffiLib.ffi_bitkitcore_rust_future_poll_void, + _UniffiLib.ffi_bitkitcore_rust_future_complete_void, + _UniffiLib.ffi_bitkitcore_rust_future_free_void, + # lift function + lambda val: None, + + + # Error FFI converter +_UniffiConverterTypePaykitError, + + ) async def test_notification(device_token: "str",secret_message: "str",notification_type: "typing.Optional[str]",custom_url: "typing.Optional[str]") -> "str": _UniffiConverterString.check_lower(device_token) @@ -15603,6 +17286,19 @@ def validate_mnemonic(mnemonic_phrase: "str") -> None: _UniffiConverterString.lower(mnemonic_phrase)) +def validate_paykit_deeplink(url: "str") -> "bool": + """ + Validates a deeplink URL without processing it. + + Use this to check if a URL is a valid Paykit deeplink before handling it. + """ + + _UniffiConverterString.check_lower(url) + + return _UniffiConverterBool.lift(_uniffi_rust_call_with_error(_UniffiConverterTypePaykitError,_UniffiLib.uniffi_bitkitcore_fn_func_validate_paykit_deeplink, + _UniffiConverterString.lower(url))) + + def wipe_all_closed_channels() -> None: _uniffi_rust_call_with_error(_UniffiConverterTypeActivityError,_UniffiLib.uniffi_bitkitcore_fn_func_wipe_all_closed_channels,) @@ -15651,6 +17347,7 @@ async def wipe_all_databases() -> "str": "ManualRefundStateEnum", "Network", "NetworkType", + "PaykitError", "PaymentState", "PaymentType", "Scanner", @@ -15678,6 +17375,7 @@ async def wipe_all_databases() -> "str": "DeepLinkResult", "DefaultLspBalanceParams", "DeviceParams", + "EndpointData", "ErrorData", "FeatureResponse", "FeeLevel", @@ -15720,21 +17418,28 @@ async def wipe_all_databases() -> "str": "LnurlPayData", "LnurlWithdrawData", "MessageSignatureResponse", + "MethodId", "MultisigRedeemScriptType", "OnChainInvoice", "OnchainActivity", + "PaykitDeeplink", "PaymentRequestMemo", "PreActivityMetadata", "PrecomposedInput", "PrecomposedOutput", "PrecomposedTransaction", "PubkyAuth", + "PublicKey", "PublicKeyResponse", "RefTransaction", "RefTxInput", "RefTxOutput", "RefundMemo", + "ScannedPaykitSession", + "SessionData", + "SessionToken", "SignedTransactionResponse", + "SupportedPayments", "TextMemo", "TxAckPaymentRequest", "TxInputType", @@ -15753,7 +17458,10 @@ async def wipe_all_databases() -> "str": "calculate_channel_liquidity_options", "create_channel_request_url", "create_cjit_entry", + "create_deeplink_from_token", "create_order", + "create_pubky_ring_session_request", + "create_session_token_from_keypair", "create_withdraw_callback_url", "decode", "delete_activity_by_id", @@ -15761,6 +17469,7 @@ async def wipe_all_databases() -> "str": "derive_bitcoin_address", "derive_bitcoin_addresses", "derive_private_key", + "deserialize_token_to_session", "entropy_to_mnemonic", "estimate_order_fee", "estimate_order_fee_full", @@ -15780,10 +17489,13 @@ async def wipe_all_databases() -> "str": "get_default_lsp_balance", "get_gift", "get_info", + "get_known_contacts", "get_lnurl_invoice", "get_min_zero_conf_tx_fee", "get_orders", "get_payment", + "get_payment_endpoint", + "get_payment_list", "get_pre_activity_metadata", "get_tags", "gift_order", @@ -15796,6 +17508,7 @@ async def wipe_all_databases() -> "str": "mnemonic_to_entropy", "mnemonic_to_seed", "open_channel", + "parse_paykit_deeplink", "refresh_active_cjit_entries", "refresh_active_orders", "register_device", @@ -15805,9 +17518,12 @@ async def wipe_all_databases() -> "str": "regtest_mine", "regtest_pay", "remove_closed_channel_by_id", + "remove_payment_endpoint", "remove_pre_activity_metadata_tags", "remove_tags", "reset_pre_activity_metadata_tags", + "serialize_session_to_token", + "set_payment_endpoint", "test_notification", "trezor_compose_transaction", "trezor_get_account_info", @@ -15832,7 +17548,10 @@ async def wipe_all_databases() -> "str": "upsert_tags", "validate_bitcoin_address", "validate_mnemonic", + "validate_paykit_deeplink", "wipe_all_closed_channels", "wipe_all_databases", + "PubkyAuthenticatedTransport", + "PubkyUnauthenticatedTransport", ] diff --git a/bindings/python/bitkitcore/libbitkitcore.dylib b/bindings/python/bitkitcore/libbitkitcore.dylib index bd394c5..ef548b2 100755 Binary files a/bindings/python/bitkitcore/libbitkitcore.dylib and b/bindings/python/bitkitcore/libbitkitcore.dylib differ diff --git a/example/main.rs b/example/main.rs index aaabf73..9a3f4c5 100644 --- a/example/main.rs +++ b/example/main.rs @@ -42,6 +42,14 @@ fn handle_decode_result(result: Result) { println!("Data: {}", data); } + Ok(Scanner::PaykitSession { data }) => { + println!("\nSuccessfully decoded Paykit Session:"); + println!("URL: {}", data.url); + println!("Action: {}", data.action); + println!("Token: {}", data.token); + println!("Parameters: {:?}", data.parameters); + } + Ok(Scanner::LnurlChannel { data }) => { println!("\nSuccessfully decoded LNURL-channel:"); println!("URI: {}", data.uri); diff --git a/src/lib.rs b/src/lib.rs index 621aa01..73707ba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,7 @@ pub use modules::scanner::{ pub use modules::lnurl; pub use modules::onchain; pub use modules::activity; +pub use modules::paykit; use crate::activity::{ActivityError, ActivityDB, OnchainActivity, LightningActivity, Activity, ActivityFilter, SortDirection, PaymentType, DbError, ClosedChannelDetails, ActivityTags, PreActivityMetadata}; use crate::modules::blocktank::{BlocktankDB, BlocktankError, IBtInfo, IBtOrder, CreateOrderOptions, BtOrderState2, IBt0ConfMinTxFeeWindow, IBtEstimateFeeResponse, IBtEstimateFeeResponse2, CreateCjitOptions, ICJitEntry, CJitStateEnum, IBtBolt11Invoice, IGift, ChannelLiquidityOptions, ChannelLiquidityParams, DefaultLspBalanceParams}; use crate::onchain::{AddressError, ValidationResult, GetAddressResponse, Network, GetAddressesResponse}; diff --git a/src/modules/mod.rs b/src/modules/mod.rs index f6bfc87..e8144ba 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -3,4 +3,5 @@ pub mod lnurl; pub mod onchain; pub mod activity; pub mod blocktank; -pub mod trezor; \ No newline at end of file +pub mod trezor; +pub mod paykit; \ No newline at end of file diff --git a/src/modules/paykit/README.md b/src/modules/paykit/README.md new file mode 100644 index 0000000..4a319b8 --- /dev/null +++ b/src/modules/paykit/README.md @@ -0,0 +1,541 @@ +# Paykit Module + +This module provides UniFFI bindings for the [paykit-rs](https://github.com/pubky/paykit-rs) library, enabling Bitkit to interact with Pubky homeservers for payment endpoint management. + +## Overview + +Paykit enables applications to: +- Import authenticated sessions from Pubky Ring via deeplinks +- Publish payment endpoints (Bitcoin addresses, Lightning invoices) to a user's Pubky homeserver +- Retrieve payment endpoints from other Pubky users +- Manage session lifecycle and authentication + +## Table of Contents +- [Core Concepts](#core-concepts) +- [User Flow](#user-flow) +- [Swift (iOS) Implementation](#swift-ios-implementation) +- [Kotlin (Android) Implementation](#kotlin-android-implementation) +- [API Reference](#api-reference) +- [Error Handling](#error-handling) +- [Testing](#testing) + +## Core Concepts + +### Sessions +Authentication with Pubky homeservers requires a session. Bitkit receives authenticated sessions as: +- **Session tokens** - Base64-encoded tokens received via deeplinks from Pubky Ring +- Sessions are created and managed by Pubky Ring, not Bitkit + +### Payment Endpoints +Payment information stored on Pubky homeservers, identified by: +- **MethodId** - Payment method type (e.g., "onchain", "lightning") +- **EndpointData** - Payment details (e.g., Bitcoin address, Lightning invoice) + +### Transports +- **PubkyAuthenticatedTransport** - For write operations (requires session) +- **PubkyUnauthenticatedTransport** - For read operations (no session needed) + +## User Flow + +### 1. Initial Setup - Connecting to Pubky Ring + +1. User navigates to Settings → "Connect Pubky" +2. Bitkit displays QR code or "Open Pubky Ring" button with URI: + ``` + pubkyring://session?callback=bitkit://session-data + ``` +3. Pubky Ring authenticates and returns session via deeplink +4. Bitkit saves session and shows "Connected" + +### 2. Publishing Payment Endpoints + +1. Bitkit generates new Bitcoin address +2. Calls `set_payment_endpoint()` with authenticated session +3. Address stored on user's homeserver +4. Bitkit monitors address for incoming payments + +### 3. Retrieving Payment Endpoints + +1. User scans/enters recipient's Pubky +2. Calls `get_payment_endpoint()` (no session required) +3. Retrieves and displays Bitcoin address +4. User can send payment + +## Swift (iOS) Implementation + +### Setup and Imports + +```swift +import bitkitcore + +class PaykitManager { + private var currentSession: PubkyAuthenticatedTransport? + private var sessionToken: String? + + init() { + // Restore session on init if available + Task { + await restoreSession() + } + } +} +``` + +### Connecting to Pubky Ring + +```swift +// Generate connection URI for QR code or deeplink +func generateConnectionURI() throws -> String { + return try createPubkyRingSessionRequest( + callbackUrl: "bitkit://paykit/session-data", + additionalParams: nil + ) + // Result: "pubkyring://session?callback=bitkit%3A%2F%2Fpaykit%2Fsession-data" +} + +// Open Pubky Ring app +func openPubkyRing() { + guard let uri = try? generateConnectionURI(), + let url = URL(string: uri) else { return } + UIApplication.shared.open(url) +} + +// Handle callback from Pubky Ring +func handlePubkyCallback(url: URL) async throws { + let urlString = url.absoluteString + + // Parse the deeplink + let deeplink = try parsePaykitDeeplink(url: urlString) + + // Extract and validate token + guard let token = deeplink.sessionToken else { + throw PaykitError.InvalidToken(message: "No session token in deeplink") + } + + // Create authenticated transport + let sessionToken = SessionToken(token: token) + let transport = try await createTransportFromSessionToken(token: sessionToken) + + // Save session + self.currentSession = transport + self.sessionToken = token + + // Persist to Keychain + saveToKeychain(key: "pubky_session", value: token) + + // Update UI + updateConnectionStatus(connected: true) +} +``` + +### Publishing Bitcoin Address + +```swift +func publishBitcoinAddress(address: String) async throws { + guard let session = currentSession else { + throw PaykitError.SessionError("No active session") + } + + let method = MethodId(id: "onchain") + let endpointData = EndpointData(data: address) + + try await session.setPaymentEndpoint(method: method, data: endpointData) + print("✅ Bitcoin address published: \(address)") +} + +// Publish Lightning invoice +func publishLightningInvoice(invoice: String) async throws { + guard let session = currentSession else { + throw PaykitError.SessionError("No active session") + } + + let method = MethodId(id: "lightning") + let endpointData = EndpointData(data: invoice) + + try await session.setPaymentEndpoint(method: method, data: endpointData) +} +``` + +### Retrieving Payment Endpoints + +```swift +func getRecipientBitcoinAddress(pubky: String) async throws -> String? { + // No session needed for reading + let transport = try PubkyUnauthenticatedTransport() + let recipientKey = PublicKey(key: pubky) + let method = MethodId(id: "onchain") + + if let endpoint = try await transport.getPaymentEndpoint( + payee: recipientKey, + method: method + ) { + return endpoint.data + } + return nil +} + +// Get all available payment methods +func getRecipientPaymentMethods(pubky: String) async throws -> [String: String] { + let transport = try PubkyUnauthenticatedTransport() + let recipientKey = PublicKey(key: pubky) + + let payments = try await transport.getPaymentList(payee: recipientKey) + + var methods: [String: String] = [:] + for (methodId, endpointData) in payments.entries { + methods[methodId.id] = endpointData.data + } + return methods +} +``` + +### Session Management + +```swift +// Restore saved session +func restoreSession() async throws { + guard let savedToken = loadFromKeychain(key: "pubky_session") else { return } + + let sessionToken = SessionToken(token: savedToken) + self.currentSession = try await createTransportFromSessionToken(token: sessionToken) + self.sessionToken = savedToken +} + +// Clear session (logout) +func clearSession() { + currentSession = nil + sessionToken = nil + deleteFromKeychain(key: "pubky_session") + updateConnectionStatus(connected: false) +} + +// Check if session exists +func hasActiveSession() -> Bool { + return currentSession != nil +} +``` + +## Kotlin (Android) Implementation + +### Setup and Initialization + +```kotlin +import bitkitcore.* +import kotlinx.coroutines.* + +class PaykitManager(private val context: Context) { + private var currentSession: PubkyAuthenticatedTransport? = null + private var sessionToken: String? = null + private val prefs = context.getSharedPreferences("paykit_prefs", Context.MODE_PRIVATE) + + init { + // Restore session on init + GlobalScope.launch { + restoreSession() + } + } +} +``` + +### Connecting to Pubky Ring + +```kotlin +// Generate connection URI for QR code or deeplink +fun generateConnectionURI(): String { + return createPubkyRingSessionRequest( + callbackUrl = "bitkit://paykit/session-data", + additionalParams = null + ) + // Result: "pubkyring://session?callback=bitkit%3A%2F%2Fpaykit%2Fsession-data" +} + +// Open Pubky Ring app +fun openPubkyRing() { + val uri = generateConnectionURI() + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(uri)) + + if (intent.resolveActivity(context.packageManager) != null) { + context.startActivity(intent) + } else { + // Prompt to install Pubky Ring + showInstallPrompt() + } +} + +// Handle callback from Pubky Ring +suspend fun handlePubkyCallback(uri: Uri) { + try { + // Parse the deeplink + val deeplink = parsePaykitDeeplink(uri.toString()) + + // Extract and validate token + val token = deeplink.sessionToken + ?: throw PaykitError.InvalidToken("No session token in deeplink") + + // Create authenticated transport + val sessionToken = SessionToken(token) + val transport = createTransportFromSessionToken(sessionToken) + + // Save session + currentSession = transport + this.sessionToken = token + + // Persist to SharedPreferences + prefs.edit().putString("pubky_session", token).apply() + + // Update UI + updateConnectionStatus(true) + } catch (e: PaykitError) { + handleError(e) + } +} +``` + +### Publishing Bitcoin Address + +```kotlin +suspend fun publishBitcoinAddress(address: String) { + val session = currentSession + ?: throw PaykitError.SessionError("No active session") + + val method = MethodId("onchain") + val endpointData = EndpointData(address) + + session.setPaymentEndpoint(method, endpointData) + Log.d("Paykit", "✅ Bitcoin address published: $address") +} + +// Publish Lightning invoice +suspend fun publishLightningInvoice(invoice: String) { + val session = currentSession + ?: throw PaykitError.SessionError("No active session") + + val method = MethodId("lightning") + val endpointData = EndpointData(invoice) + + session.setPaymentEndpoint(method, endpointData) +} +``` + +### Retrieving Payment Endpoints + +```kotlin +suspend fun getRecipientBitcoinAddress(pubky: String): String? { + return try { + // No session needed for reading + val transport = PubkyUnauthenticatedTransport() + val recipientKey = PublicKey(pubky) + val method = MethodId("onchain") + + transport.getPaymentEndpoint(recipientKey, method)?.data + } catch (e: PaykitError) { + Log.e("Paykit", "Failed to get recipient address", e) + null + } +} + +// Get all available payment methods +suspend fun getRecipientPaymentMethods(pubky: String): Map { + val transport = PubkyUnauthenticatedTransport() + val recipientKey = PublicKey(pubky) + + val payments = transport.getPaymentList(recipientKey) + + return payments.entries.mapKeys { it.key.id } + .mapValues { it.value.data } +} +``` + +### Session Management + +```kotlin +// Restore saved session +suspend fun restoreSession() { + prefs.getString("pubky_session", null)?.let { savedToken -> + try { + val sessionToken = SessionToken(savedToken) + currentSession = createTransportFromSessionToken(sessionToken) + this.sessionToken = savedToken + } catch (e: PaykitError) { + // Session invalid or expired + clearSession() + } + } +} + +// Clear session (logout) +fun clearSession() { + currentSession = null + sessionToken = null + prefs.edit().remove("pubky_session").apply() + updateConnectionStatus(false) +} +``` + +## API Reference + +### Core Types + +| Type | Description | Fields | +|------|-------------|--------| +| `SessionToken` | Wrapper for session token string | `token: String` | +| `MethodId` | Payment method identifier | `id: String` | +| `EndpointData` | Payment endpoint data | `data: String` | +| `PublicKey` | Pubky public key | `key: String` | +| `SupportedPayments` | Collection of payment methods | `entries: Map` | + +### Session Functions + +| Function | Description | Parameters | Returns | +|----------|-------------|------------|---------| +| `createPubkyRingSessionRequest` | Generate URL to request session from Pubky Ring | `callbackUrl: String`, `additionalParams: Map?` | `String` | +| `parsePaykitDeeplink` | Parse deeplink URL | `url: String` | `PaykitDeeplink` | +| `createTransportFromSessionToken` | Create session from token | `token: SessionToken` | `PubkyAuthenticatedTransport` | + +### Authenticated Operations (Requires Session) + +| Function | Description | Parameters | Returns | +|----------|-------------|------------|---------| +| `setPaymentEndpoint` | Store payment endpoint | `method: MethodId`, `data: EndpointData` | `void` | +| `removePaymentEndpoint` | Remove payment endpoint | `method: MethodId` | `void` | + +### Unauthenticated Operations (No Session Required) + +| Function | Description | Parameters | Returns | +|----------|-------------|------------|---------| +| `getPaymentEndpoint` | Retrieve specific payment endpoint | `pubky: PublicKey`, `method: MethodId` | `EndpointData?` | +| `getPaymentList` | Get all payment methods | `pubky: PublicKey` | `SupportedPayments` | +| `getKnownContacts` | Get user's contacts | `pubky: PublicKey` | `List` | + +## Error Handling + +### Error Types + +```swift +// Swift +enum PaykitError: Error { + case SessionError(String) // Session-related errors + case Transport(String) // Network/transport errors + case InvalidToken(String) // Token validation errors + case NotFound(String) // Resource not found +} +``` + +```kotlin +// Kotlin +sealed class PaykitError : Exception() { + data class SessionError(val message: String) : PaykitError() + data class Transport(val message: String) : PaykitError() + data class InvalidToken(val message: String) : PaykitError() + data class NotFound(val message: String) : PaykitError() +} +``` + +### Error Handling Best Practices + +1. **Session Expiration**: When a session expires, clear it and prompt for reconnection +2. **Network Errors**: Implement retry logic with exponential backoff +3. **Invalid Tokens**: Clear invalid tokens and request new authentication +4. **Not Found**: Handle gracefully when payment endpoints don't exist + +## Testing + +### Unit Test Example (Swift) + +```swift +func testPaykitDeeplinkFlow() async throws { + // Test deeplink parsing + let deeplink = "bitkit://paykit/session?token=eyJ0ZXN0IjoidG9rZW4ifQ" + let parsed = try parsePaykitDeeplink(url: deeplink) + XCTAssertNotNil(parsed.sessionToken) + + // Test session token validation + let sessionToken = SessionToken(token: "eyJ0ZXN0IjoidG9rZW4ifQ") + XCTAssertNoThrow(try sessionToken.validate()) + + // Mock session creation from token + // In real tests, you would use a valid token from Pubky Ring + let mockToken = SessionToken(token: "valid_base64_encoded_session_data") + // let transport = try await createTransportFromSessionToken(token: mockToken) + // XCTAssertNotNil(transport) +} + +func testPaymentEndpoints() async throws { + // Test unauthenticated read operations + let transport = try PubkyUnauthenticatedTransport() + let pubkey = PublicKey(key: "test_pubky_address") + let method = MethodId(id: "onchain") + + // Try to retrieve payment endpoint (may return nil if not set) + let endpoint = try await transport.getPaymentEndpoint( + payee: pubkey, + method: method + ) + // Assert based on expected test data +} +``` + +### Integration Test Example (Kotlin) + +```kotlin +@Test +fun testPaykitDeeplinkFlow() = runBlocking { + // Test deeplink parsing + val deeplink = "bitkit://paykit/session?token=eyJ0ZXN0IjoidG9rZW4ifQ" + val parsed = parsePaykitDeeplink(deeplink) + assertNotNull(parsed.sessionToken) + + // Test session token validation + val sessionToken = SessionToken("eyJ0ZXN0IjoidG9rZW4ifQ") + // Validation happens during transport creation + + // Mock session creation from token + // In real tests, you would use a valid token from Pubky Ring + val mockToken = SessionToken("valid_base64_encoded_session_data") + // val transport = createTransportFromSessionToken(mockToken) + // assertNotNull(transport) +} + +@Test +fun testPaymentEndpoints() = runBlocking { + // Test unauthenticated read operations + val transport = PubkyUnauthenticatedTransport() + val pubkey = PublicKey("test_pubky_address") + val method = MethodId("onchain") + + // Try to retrieve payment endpoint (may return null if not set) + val endpoint = transport.getPaymentEndpoint(pubkey, method) + // Assert based on expected test data +} +``` + +## Security Considerations + +1. **Session Storage**: Always store session tokens in secure storage: + - iOS: Use Keychain Services + - Android: Use Android Keystore or encrypted SharedPreferences + +2. **Token Expiration**: Implement proper token refresh when sessions expire + +3. **Transport Security**: All communication with homeservers uses HTTPS + +4. **Key Management**: Never store unencrypted private keys + +## Platform-Specific Notes + +### iOS +- Use `@MainActor` for UI updates after async operations +- Handle `Info.plist` URL scheme registration for deeplinks +- Implement `application(_:open:options:)` in AppDelegate + +### Android +- Register intent filters in AndroidManifest.xml for deeplinks +- Use Coroutines for async operations +- Handle lifecycle-aware session management + +## Support + +For issues or questions: +- Review test examples in `src/modules/paykit/tests.rs` +- Check integration tests in `src/modules/paykit/integration_tests.rs` +- File issues at: https://github.com/synonymdev/bitkit-core/issues \ No newline at end of file diff --git a/src/modules/paykit/deeplink_handler.rs b/src/modules/paykit/deeplink_handler.rs new file mode 100644 index 0000000..4551ae2 --- /dev/null +++ b/src/modules/paykit/deeplink_handler.rs @@ -0,0 +1,451 @@ +//! Deeplink handler for Paykit session management. +//! +//! This module provides utilities for handling deeplinks that contain +//! Pubky session tokens for authentication. + +use crate::paykit::errors::PaykitError; +use crate::paykit::session_serialization::{SessionToken, create_transport_from_session_token}; +use crate::paykit::PubkyAuthenticatedTransport; +use std::collections::HashMap; + +/// Represents a parsed deeplink with Paykit session information +#[derive(Debug, Clone, uniffi::Record)] +pub struct PaykitDeeplink { + /// The action to perform (e.g., "session", "payment", "connect") + pub action: String, + /// The session token if present + pub session_token: Option, + /// Additional parameters from the deeplink + pub parameters: HashMap, +} + +impl PaykitDeeplink { + /// Creates a new PaykitDeeplink + pub fn new(action: impl Into) -> Self { + Self { + action: action.into(), + session_token: None, + parameters: HashMap::new(), + } + } + + /// Sets the session token + pub fn with_token(mut self, token: impl Into) -> Self { + self.session_token = Some(token.into()); + self + } + + /// Adds a parameter + pub fn with_param(mut self, key: impl Into, value: impl Into) -> Self { + self.parameters.insert(key.into(), value.into()); + self + } +} + +/// Parses a deeplink URL into a PaykitDeeplink structure. +/// +/// # Supported URL Formats +/// - `myapp://paykit/session?token=` +/// - `myapp://paykit/connect?token=&return_url=` +/// - `https://myapp.com/paykit/session?token=` +/// +/// # Example +/// ``` +/// let url = "myapp://paykit/session?token=eyJwdWJsaWNfa2V5IjoiLi4uIn0"; +/// let deeplink = parse_paykit_deeplink(url)?; +/// assert_eq!(deeplink.action, "session"); +/// assert!(deeplink.session_token.is_some()); +/// ``` +#[uniffi::export] +pub fn parse_paykit_deeplink(url: String) -> Result { + // Parse the URL + let parsed = url::Url::parse(&url).map_err(|e| PaykitError::SessionError( + format!("Invalid deeplink URL: {}", e) + ))?; + + // Extract the path to determine the action + // For custom schemes like "myapp://", the host becomes part of the path + let (is_paykit, action) = if parsed.scheme() == "paykit" { + // For paykit:// scheme, the host is the action (e.g., paykit://session?token=...) + let host = parsed.host_str().unwrap_or("session"); + let action = if host.is_empty() { "session" } else { host }; + (true, action.to_string()) + } else if parsed.scheme() == "http" || parsed.scheme() == "https" { + // For HTTP(S) URLs, check the path + let path = parsed.path().trim_start_matches('/'); + let path_parts: Vec<&str> = path.split('/').collect(); + + if path_parts.contains(&"paykit") { + let action = path_parts + .iter() + .skip_while(|&&p| p != "paykit") + .nth(1) + .unwrap_or(&"session") + .to_string(); + (true, action) + } else { + (false, String::new()) + } + } else { + // For custom schemes, the host is "paykit" and path is the action + let host = parsed.host_str().unwrap_or(""); + if host == "paykit" { + let action = parsed.path().trim_start_matches('/'); + let action = if action.is_empty() { "session" } else { action }; + (true, action.to_string()) + } else { + (false, String::new()) + } + }; + + if !is_paykit { + return Err(PaykitError::SessionError( + "Not a valid Paykit deeplink".to_string() + )); + } + + // Parse query parameters + let mut deeplink = PaykitDeeplink::new(action); + + for (key, value) in parsed.query_pairs() { + if key == "token" { + deeplink.session_token = Some(value.to_string()); + } else { + deeplink.parameters.insert(key.to_string(), value.to_string()); + } + } + + Ok(deeplink) +} + +/// Handles a Paykit deeplink and returns an authenticated transport if successful. +/// +/// This is the main entry point for processing deeplinks in your app. +/// +/// # Example +/// ``` +/// // In your app's deeplink handler +/// let url = "myapp://paykit/session?token=..."; +/// match handle_paykit_deeplink(url).await { +/// Ok(transport) => { +/// // Use the authenticated transport for paykit operations +/// set_payment_endpoint(&transport, method, data).await?; +/// } +/// Err(e) => { +/// // Handle error (invalid token, expired, etc.) +/// } +/// } +/// ``` +#[cfg(feature = "pubky")] +pub async fn handle_paykit_deeplink(url: String) -> Result { + // Parse the deeplink + let deeplink = parse_paykit_deeplink(url)?; + + // Check if we have a session token + let token_str = deeplink + .session_token + .ok_or_else(|| PaykitError::SessionError( + "No session token found in deeplink".to_string() + ))?; + + // Create a SessionToken + let token = SessionToken::new(token_str); + + // Create authenticated transport from the token + create_transport_from_session_token(token).await +} + +/// Handles a Paykit deeplink (non-pubky stub) +#[cfg(not(feature = "pubky"))] +pub async fn handle_paykit_deeplink(_url: String) -> Result { + Err(PaykitError::SessionError( + "Deeplink handling requires the 'pubky' feature to be enabled".to_string() + )) +} + +/// Creates a session request URL to send to Pubky Ring for authentication. +/// +/// This generates a URL that Bitkit displays as a QR code or uses to open Pubky Ring. +/// When Pubky Ring completes authentication, it will return the session data +/// via the provided callback URL. +/// +/// # Parameters +/// - `callback_url`: The URL scheme and path where Pubky Ring should return the session. +/// Example: "bitkit://paykit/session-data" or "bitkit://session" +/// - `additional_params`: Optional additional parameters to include in the request URL +/// +/// # Returns +/// A URL string like: `pubkyring://session?callback=bitkit%3A%2F%2Fpaykit%2Fsession-data` +/// +/// # Example +/// ``` +/// // Generate URL for QR code or "Open Pubky Ring" button +/// let request_url = create_pubky_ring_session_request( +/// "bitkit://paykit/session-data".to_string(), +/// None +/// )?; +/// // Result: "pubkyring://session?callback=bitkit%3A%2F%2Fpaykit%2Fsession-data" +/// +/// // With additional parameters +/// let mut params = HashMap::new(); +/// params.insert("app_name".to_string(), "Bitkit".to_string()); +/// let request_url = create_pubky_ring_session_request( +/// "bitkit://paykit/session-data".to_string(), +/// Some(params) +/// )?; +/// ``` +#[uniffi::export] +pub fn create_pubky_ring_session_request( + callback_url: String, + additional_params: Option>, +) -> Result { + // Validate callback URL format + if callback_url.is_empty() { + return Err(PaykitError::SessionError( + "Callback URL cannot be empty".to_string() + )); + } + + // URL-encode the callback + let encoded_callback = urlencoding::encode(&callback_url); + + // Build the Pubky Ring session request URL + let mut url = format!("pubkyring://session?callback={}", encoded_callback); + + // Add any additional parameters + if let Some(params) = additional_params { + for (key, value) in params { + let encoded_value = urlencoding::encode(&value); + url.push_str(&format!("&{}={}", key, encoded_value)); + } + } + + Ok(url) +} + +/// Creates a deeplink URL from a session token. +/// +/// Use this to generate a deeplink that can be shared with another app instance. +/// +/// # Example +/// ``` +/// let token = create_session_token_from_keypair( +/// public_key, +/// secret_key, +/// None, +/// Some(3600) +/// )?; +/// +/// let deeplink_url = create_deeplink_from_token( +/// "myapp://", +/// "session", +/// token, +/// None +/// )?; +/// // Result: "myapp://paykit/session?token=..." +/// ``` +#[uniffi::export] +pub fn create_deeplink_from_token( + base_url: String, + action: String, + token: SessionToken, + additional_params: Option>, +) -> Result { + // Validate the token first + token.validate()?; + + // Build the URL + let mut url = if base_url.ends_with("://") { + format!("{}paykit/{}", base_url, action) + } else if base_url.ends_with('/') { + format!("{}paykit/{}", base_url, action) + } else { + format!("{}/paykit/{}", base_url, action) + }; + + // Add the token as a query parameter + url.push_str(&format!("?token={}", token.token)); + + // Add any additional parameters + if let Some(params) = additional_params { + for (key, value) in params { + // URL encode the values + let encoded_value = urlencoding::encode(&value); + url.push_str(&format!("&{}={}", key, encoded_value)); + } + } + + Ok(url) +} + +/// Validates a deeplink URL without processing it. +/// +/// Use this to check if a URL is a valid Paykit deeplink before handling it. +#[uniffi::export] +pub fn validate_paykit_deeplink(url: String) -> Result { + let deeplink = parse_paykit_deeplink(url)?; + + // Check if it's a session action with a token + if deeplink.action == "session" && deeplink.session_token.is_some() { + // Validate the token format + let token = SessionToken::new(deeplink.session_token.unwrap()); + token.validate()?; + return Ok(true); + } + + // For other actions, just check if it's a valid paykit deeplink + Ok(true) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::paykit::session_serialization::{create_session_token_from_keypair, deserialize_token_to_session}; + + #[test] + fn test_create_pubky_ring_session_request() { + // Basic test + let url = create_pubky_ring_session_request( + "bitkit://paykit/session-data".to_string(), + None, + ).unwrap(); + + assert!(url.starts_with("pubkyring://session?callback=")); + assert!(url.contains("bitkit")); + + // URL should be properly encoded + assert!(url.contains("%3A%2F%2F") || url.contains("bitkit")); // :// encoded + } + + #[test] + fn test_create_pubky_ring_session_request_with_params() { + let mut params = HashMap::new(); + params.insert("app_name".to_string(), "Bitkit".to_string()); + params.insert("version".to_string(), "1.0".to_string()); + + let url = create_pubky_ring_session_request( + "bitkit://session".to_string(), + Some(params), + ).unwrap(); + + assert!(url.contains("pubkyring://session")); + assert!(url.contains("callback=")); + assert!(url.contains("app_name=Bitkit")); + assert!(url.contains("version=1.0")); + } + + #[test] + fn test_create_pubky_ring_session_request_empty_callback() { + let result = create_pubky_ring_session_request( + "".to_string(), + None, + ); + + assert!(result.is_err()); + } + + #[test] + fn test_parse_deeplink() { + // Test custom scheme + let url = "myapp://paykit/session?token=abc123&return_url=home"; + let deeplink = parse_paykit_deeplink(url.to_string()).unwrap(); + assert_eq!(deeplink.action, "session"); + assert_eq!(deeplink.session_token, Some("abc123".to_string())); + assert_eq!(deeplink.parameters.get("return_url"), Some(&"home".to_string())); + + // Test HTTPS URL + let url2 = "https://app.example.com/paykit/connect?token=xyz789"; + let deeplink2 = parse_paykit_deeplink(url2.to_string()).unwrap(); + assert_eq!(deeplink2.action, "connect"); + assert_eq!(deeplink2.session_token, Some("xyz789".to_string())); + } + + #[test] + fn test_create_deeplink() { + // Create a valid base64 token for testing + let valid_base64 = "eyJ0ZXN0IjoidmFsdWUifQ"; // {"test":"value"} in base64 + let token = SessionToken::new(valid_base64); + + // Test with custom scheme + let url = create_deeplink_from_token( + "myapp://".to_string(), + "session".to_string(), + token.clone(), + None, + ) + .unwrap(); + assert_eq!(url, format!("myapp://paykit/session?token={}", valid_base64)); + + // Test with additional params + let mut params = HashMap::new(); + params.insert("return_url".to_string(), "home screen".to_string()); + + let url2 = create_deeplink_from_token( + "https://app.example.com".to_string(), + "connect".to_string(), + token, + Some(params), + ) + .unwrap(); + assert!(url2.contains(&format!("token={}", valid_base64))); + assert!(url2.contains("return_url=home%20screen")); + } + + #[test] + fn test_validate_deeplink() { + // Create a valid token first + let token = create_session_token_from_keypair( + "public".to_string(), + "secret".to_string(), + None, + None, + ) + .unwrap(); + + let url = create_deeplink_from_token( + "myapp://".to_string(), + "session".to_string(), + token, + None, + ) + .unwrap(); + + // Should be valid + assert!(validate_paykit_deeplink(url).unwrap()); + + // Invalid URL should fail + assert!(validate_paykit_deeplink("not-a-url".to_string()).is_err()); + } + + #[test] + fn test_deeplink_roundtrip() { + // Create session token + let token = create_session_token_from_keypair( + "test_public_key".to_string(), + "test_secret_key".to_string(), + Some("https://homeserver.example".to_string()), + Some(3600), + ) + .unwrap(); + + // Create deeplink + let url = create_deeplink_from_token( + "myapp://".to_string(), + "session".to_string(), + token, + None, + ) + .unwrap(); + + // Parse it back + let parsed = parse_paykit_deeplink(url).unwrap(); + assert_eq!(parsed.action, "session"); + assert!(parsed.session_token.is_some()); + + // Deserialize the token + let session_token = SessionToken::new(parsed.session_token.unwrap()); + let session_data = deserialize_token_to_session(session_token).unwrap(); + assert_eq!(session_data.public_key, "test_public_key"); + assert_eq!(session_data.homeserver_url, Some("https://homeserver.example".to_string())); + } +} \ No newline at end of file diff --git a/src/modules/paykit/errors.rs b/src/modules/paykit/errors.rs new file mode 100644 index 0000000..3e3b80e --- /dev/null +++ b/src/modules/paykit/errors.rs @@ -0,0 +1,68 @@ +use thiserror::Error; +use paykit_lib::PaykitError as ExternalPaykitError; + +/// Domain-specific error type for Paykit operations. +#[derive(Debug, Clone, uniffi::Error, Error)] +#[non_exhaustive] +pub enum PaykitError { + #[error("Not implemented: {0}")] + Unimplemented(String), + #[error("Transport error: {0}")] + Transport(String), + #[error("Invalid public key: {0}")] + InvalidPublicKey(String), + #[error("Invalid method ID: {0}")] + InvalidMethodId(String), + #[error("Invalid endpoint data: {0}")] + InvalidEndpointData(String), + #[error("Session error: {0}")] + SessionError(String), +} + +impl From for PaykitError { + fn from(value: ExternalPaykitError) -> Self { + match value { + ExternalPaykitError::Unimplemented(msg) => PaykitError::Unimplemented(msg.to_string()), + ExternalPaykitError::Transport(msg) => PaykitError::Transport(msg), + } + } +} + +impl From for ExternalPaykitError { + fn from(value: PaykitError) -> Self { + match value { + PaykitError::Unimplemented(message) => { + ExternalPaykitError::Transport(format!("Unimplemented: {}", message)) + } + PaykitError::Transport(message) => ExternalPaykitError::Transport(message), + PaykitError::InvalidPublicKey(message) => { + ExternalPaykitError::Transport(format!("Invalid public key: {}", message)) + } + PaykitError::InvalidMethodId(message) => { + ExternalPaykitError::Transport(format!("Invalid method ID: {}", message)) + } + PaykitError::InvalidEndpointData(message) => { + ExternalPaykitError::Transport(format!("Invalid endpoint data: {}", message)) + } + PaykitError::SessionError(message) => { + ExternalPaykitError::Transport(format!("Session error: {}", message)) + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_error_conversion() { + let external_error = ExternalPaykitError::Transport("test error".to_string()); + let paykit_error: PaykitError = external_error.into(); + + match paykit_error { + PaykitError::Transport(message) => assert_eq!(message, "test error"), + _ => panic!("Wrong error variant"), + } + } +} diff --git a/src/modules/paykit/implementation.rs b/src/modules/paykit/implementation.rs new file mode 100644 index 0000000..154ae17 --- /dev/null +++ b/src/modules/paykit/implementation.rs @@ -0,0 +1,294 @@ +use paykit_lib::{ + PubkyAuthenticatedTransport as ExternalPubkyAuthenticatedTransport, + PubkyUnauthenticatedTransport as ExternalPubkyUnauthenticatedTransport, +}; +use std::convert::TryInto; + +use crate::paykit::errors::PaykitError; +use crate::paykit::types::{EndpointData, MethodId, PublicKey, SupportedPayments}; + +/// Authenticated transport wrapper for Paykit write operations. +#[derive(Clone, uniffi::Object)] +pub struct PubkyAuthenticatedTransport { + pub(crate) inner: ExternalPubkyAuthenticatedTransport, +} + +#[uniffi::export] +impl PubkyAuthenticatedTransport { + /// Creates a new authenticated transport. + /// Note: This requires proper session initialization which should be handled + /// by the application layer. For now, this returns an error indicating the + /// need for external session management. + #[uniffi::constructor] + pub fn new() -> Result { + Err(PaykitError::SessionError( + "Direct session creation not supported. Initialize session externally through Pubky SDK".to_string(), + )) + } + + + /// Stores or updates a payment endpoint. + /// + /// # Parameters + /// - `method`: Payment method identifier (e.g., "lightning", "onchain") + /// - `data`: Endpoint data payload (UTF-8 JSON or other text format) + pub async fn set_payment_endpoint( + &self, + method: MethodId, + data: EndpointData, + ) -> Result<(), PaykitError> { + set_payment_endpoint(self, method, data).await + } + + /// Removes a payment endpoint. + /// + /// # Parameters + /// - `method`: Payment method identifier to remove + /// + /// # Returns + /// - `Ok(())` on successful removal + /// - `Err` if the endpoint doesn't exist or transport fails + pub async fn remove_payment_endpoint(&self, method: MethodId) -> Result<(), PaykitError> { + remove_payment_endpoint(self, method).await + } +} + +impl From for PubkyAuthenticatedTransport { + fn from(inner: ExternalPubkyAuthenticatedTransport) -> Self { + Self { inner } + } +} + +/// Unauthenticated transport wrapper for Paykit read operations. +#[derive(Clone, uniffi::Object)] +pub struct PubkyUnauthenticatedTransport { + pub(crate) inner: ExternalPubkyUnauthenticatedTransport, +} + +#[uniffi::export] +impl PubkyUnauthenticatedTransport { + /// Creates a new unauthenticated transport for reading public payment data. + #[uniffi::constructor] + pub fn new() -> Result { + let inner = ExternalPubkyUnauthenticatedTransport::try_new() + .map_err(|e| PaykitError::from(e))?; + Ok(Self { inner }) + } + + /// Retrieves all supported payment methods for a given payee. + /// + /// # Parameters + /// - `payee`: Public key of the payee to query + /// + /// # Returns + /// - `Ok(SupportedPayments)` with map of method IDs to endpoint data + /// - Returns empty map if no endpoints are published + /// - `Err` only on transport failures + pub async fn get_payment_list(&self, payee: &PublicKey) -> Result { + get_payment_list(self, payee).await + } + + /// Retrieves a specific payment endpoint for a payee and method. + /// + /// # Parameters + /// - `payee`: Public key of the payee + /// - `method`: Payment method identifier to query + /// + /// # Returns + /// - `Ok(Some(EndpointData))` if the endpoint exists + /// - `Ok(None)` if the endpoint is not published + /// - `Err` only on transport failures + pub async fn get_payment_endpoint( + &self, + payee: &PublicKey, + method: &MethodId, + ) -> Result, PaykitError> { + get_payment_endpoint(self, payee, method).await + } + + /// Returns known contacts (follows) of a given public key. + /// + /// # Parameters + /// - `key`: Public key to query for contacts + /// + /// # Returns + /// - `Ok(Vec)` with list of known contacts + /// - Returns empty vector if no contacts are stored + /// - `Err` only on transport failures + pub async fn get_known_contacts(&self, key: &PublicKey) -> Result, PaykitError> { + get_known_contacts(self, key).await + } +} + +impl From for PubkyUnauthenticatedTransport { + fn from(inner: ExternalPubkyUnauthenticatedTransport) -> Self { + Self { inner } + } +} + +/// Stores or updates a payment endpoint via the authenticated transport. +/// +/// # Parameters +/// - `client`: Authenticated transport client +/// - `method`: Payment method identifier (e.g., "lightning", "onchain") +/// - `data`: Endpoint data payload (UTF-8 JSON or other text format) +/// +/// # Example +/// ``` +/// let method = MethodId { id: "lightning".to_string() }; +/// let data = EndpointData { data: r#"{"bolt11":"lnbc..."}"#.to_string() }; +/// set_payment_endpoint(&client, method, data).await?; +/// ``` +#[uniffi::export] +pub async fn set_payment_endpoint( + client: &PubkyAuthenticatedTransport, + method: MethodId, + data: EndpointData, +) -> Result<(), PaykitError> { + paykit_lib::set_payment_endpoint(&client.inner, method.into(), data.into()) + .await + .map_err(|e| e.into()) +} + +/// Removes a payment endpoint via the authenticated transport. +/// +/// # Parameters +/// - `client`: Authenticated transport client +/// - `method`: Payment method identifier to remove +/// +/// # Returns +/// - `Ok(())` on successful removal +/// - `Err` if the endpoint doesn't exist or transport fails +#[uniffi::export] +pub async fn remove_payment_endpoint( + client: &PubkyAuthenticatedTransport, + method: MethodId, +) -> Result<(), PaykitError> { + paykit_lib::remove_payment_endpoint(&client.inner, method.into()) + .await + .map_err(|e| e.into()) +} + +/// Retrieves all supported payment methods for a given payee. +/// +/// # Parameters +/// - `reader`: Unauthenticated transport for reading public data +/// - `payee`: Public key of the payee to query +/// +/// # Returns +/// - `Ok(SupportedPayments)` with map of method IDs to endpoint data +/// - Returns empty map if no endpoints are published +/// - `Err` only on transport failures +/// +/// # Example +/// ``` +/// let reader = PubkyUnauthenticatedTransport::new()?; +/// let payee = PublicKey { key: "...".to_string() }; +/// let payments = get_payment_list(&reader, &payee).await?; +/// for (method_id, data) in payments.entries { +/// println!("Method: {}, Data: {}", method_id, data.data); +/// } +/// ``` +#[uniffi::export] +pub async fn get_payment_list( + reader: &PubkyUnauthenticatedTransport, + payee: &PublicKey, +) -> Result { + let external_key: paykit_lib::PublicKey = payee.clone() + .try_into() + .map_err(|e: String| PaykitError::InvalidPublicKey(e))?; + paykit_lib::get_payment_list(&reader.inner, &external_key) + .await + .map(|p| p.into()) + .map_err(|e| e.into()) +} + +/// Retrieves a specific payment endpoint for a payee and method. +/// +/// # Parameters +/// - `reader`: Unauthenticated transport for reading public data +/// - `payee`: Public key of the payee +/// - `method`: Payment method identifier to query +/// +/// # Returns +/// - `Ok(Some(EndpointData))` if the endpoint exists +/// - `Ok(None)` if the endpoint is not published +/// - `Err` only on transport failures +/// +/// # Example +/// ``` +/// let reader = PubkyUnauthenticatedTransport::new()?; +/// let payee = PublicKey { key: "...".to_string() }; +/// let method = MethodId { id: "lightning".to_string() }; +/// if let Some(endpoint) = get_payment_endpoint(&reader, &payee, &method).await? { +/// println!("Lightning endpoint: {}", endpoint.data); +/// } +/// ``` +#[uniffi::export] +pub async fn get_payment_endpoint( + reader: &PubkyUnauthenticatedTransport, + payee: &PublicKey, + method: &MethodId, +) -> Result, PaykitError> { + let external_key: paykit_lib::PublicKey = payee.clone() + .try_into() + .map_err(|e: String| PaykitError::InvalidPublicKey(e))?; + let external_method: paykit_lib::MethodId = method.clone().into(); + paykit_lib::get_payment_endpoint(&reader.inner, &external_key, &external_method) + .await + .map(|opt| opt.map(|e| e.into())) + .map_err(|e| e.into()) +} + +/// Returns known contacts (follows) of a given public key. +/// +/// # Parameters +/// - `reader`: Unauthenticated transport for reading public data +/// - `key`: Public key to query for contacts +/// +/// # Returns +/// - `Ok(Vec)` with list of known contacts +/// - Returns empty vector if no contacts are stored +/// - `Err` only on transport failures +/// +/// # Example +/// ``` +/// let reader = PubkyUnauthenticatedTransport::new()?; +/// let user = PublicKey { key: "...".to_string() }; +/// let contacts = get_known_contacts(&reader, &user).await?; +/// for contact in contacts { +/// println!("Contact: {}", contact.key); +/// } +/// ``` +#[uniffi::export] +pub async fn get_known_contacts( + reader: &PubkyUnauthenticatedTransport, + key: &PublicKey, +) -> Result, PaykitError> { + let external_key: paykit_lib::PublicKey = key.clone() + .try_into() + .map_err(|e: String| PaykitError::InvalidPublicKey(e))?; + paykit_lib::get_known_contacts(&reader.inner, &external_key) + .await + .map(|contacts| contacts.into_iter().map(|c| c.into()).collect()) + .map_err(|e| e.into()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_unauthenticated_transport_creation() { + // This test will fail in CI without a Pubky network, but demonstrates the API + let result = PubkyUnauthenticatedTransport::new(); + // We expect this to either succeed or fail with a transport error, not unimplemented + match result { + Ok(_) => println!("Successfully created unauthenticated transport"), + Err(PaykitError::Transport(..)) => { + println!("Transport error (expected in test environment)") + } + Err(e) => panic!("Unexpected error type: {:?}", e), + } + } +} diff --git a/src/modules/paykit/integration_tests.rs b/src/modules/paykit/integration_tests.rs new file mode 100644 index 0000000..bbfe27b --- /dev/null +++ b/src/modules/paykit/integration_tests.rs @@ -0,0 +1,189 @@ +//! Integration tests for the Paykit module using real Pubky credentials. +//! +//! These tests require a Pubky network connection and use the recovery.pkarr file +//! with password "password" for authentication. + +#[cfg(all(test, feature = "pubky"))] +mod integration_tests { + use crate::paykit::*; + use crate::paykit::session_helper::{SessionConfig, create_session_from_pkarr}; + + // Test credentials + const PKARR_PATH: &str = "src/modules/paykit/recovery.pkarr"; + const PASSWORD: &str = "password"; + + /// Helper function to create a Pubky session from the pkarr file + async fn create_test_session() -> Result { + let config = SessionConfig::new(PKARR_PATH, PASSWORD); + let transport = create_session_from_pkarr(config).await?; + Ok(PubkyAuthenticatedTransport::from(transport)) + } + + #[tokio::test] + async fn test_with_real_credentials() { + println!("Testing with recovery.pkarr file..."); + + // Verify the pkarr file exists + assert!( + std::path::Path::new(PKARR_PATH).exists(), + "recovery.pkarr file not found at {}", + PKARR_PATH + ); + + // Try to create a session + match create_test_session().await { + Ok(session) => { + println!("Session created successfully!"); + // Session is valid - we have authenticated transport + } + Err(PaykitError::SessionError(msg)) => { + // Network errors are acceptable in CI/test environments + println!("Session error (may be expected without network): {}", msg); + } + Err(e) => { + println!("Other error: {:?}", e); + } + } + } + + #[tokio::test] + async fn test_read_operations_with_unauthenticated_transport() { + // This test can run without authentication + println!("Testing unauthenticated read operations..."); + + // Create unauthenticated transport + let reader = match PubkyUnauthenticatedTransport::new() { + Ok(r) => r, + Err(e) => { + println!("Skipping test - no Pubky network available: {:?}", e); + return; + } + }; + + // Use a test public key (this would be derived from the recovery.pkarr) + // For now, use a placeholder that will return empty results + let test_pubkey = PublicKey::new("a".repeat(64)); // Valid format placeholder + + // Test getting payment list (should be empty for new account) + match get_payment_list(&reader, &test_pubkey).await { + Ok(payments) => { + println!("Payment list retrieved. Count: {}", payments.entries.len()); + // For a new account, we expect this to be empty + if payments.entries.is_empty() { + println!("No payment methods found (expected for new account)"); + } else { + for (method, data) in &payments.entries { + println!("Found payment method: {} -> {}", method, data.data); + } + } + } + Err(PaykitError::Transport(message)) if message.contains("NOT_FOUND") => { + println!("No payment data found for this public key (expected for new account)"); + } + Err(e) => { + println!("Error getting payment list: {:?}", e); + } + } + + // Test getting specific endpoint (should be None for new account) + let lightning_method = MethodId::lightning(); + match get_payment_endpoint(&reader, &test_pubkey, &lightning_method).await { + Ok(Some(endpoint)) => { + println!("Lightning endpoint found: {}", endpoint.data); + } + Ok(None) => { + println!("No lightning endpoint found (expected for new account)"); + } + Err(e) => { + println!("Error getting lightning endpoint: {:?}", e); + } + } + + // Test getting known contacts (should be empty for new account) + match get_known_contacts(&reader, &test_pubkey).await { + Ok(contacts) => { + println!("Known contacts count: {}", contacts.len()); + if contacts.is_empty() { + println!("No contacts found (expected for new account)"); + } else { + for contact in &contacts { + println!("Contact: {}", contact); + } + } + } + Err(e) => { + println!("Error getting contacts: {:?}", e); + } + } + } + + #[tokio::test] + async fn test_write_and_read_cycle() { + println!("Testing write and read cycle with real credentials..."); + + // Create an authenticated session from recovery.pkarr + let auth_transport = match create_test_session().await { + Ok(transport) => transport, + Err(e) => { + println!("Skipping test - could not create session: {:?}", e); + return; + } + }; + + println!("Session created successfully!"); + + // Write a test onchain endpoint + let method = MethodId::onchain(); + let test_data = EndpointData { + data: "bc1qtest123456789".to_string(), + }; + + // Set the payment endpoint + match set_payment_endpoint(&auth_transport, method.clone(), test_data.clone()).await { + Ok(()) => { + println!("Payment endpoint set successfully"); + } + Err(e) => { + println!("Failed to set payment endpoint: {:?}", e); + return; + } + } + + // Read it back using unauthenticated transport + let reader = match PubkyUnauthenticatedTransport::new() { + Ok(r) => r, + Err(e) => { + println!("Failed to create reader: {:?}", e); + return; + } + }; + + // Note: We'd need the public key from the session to read it back + // For now, just verify the write succeeded + println!("Write operation completed successfully"); + + // Clean up - remove the test endpoint + match remove_payment_endpoint(&auth_transport, method).await { + Ok(()) => { + println!("Test endpoint cleaned up"); + } + Err(e) => { + println!("Failed to clean up endpoint: {:?}", e); + } + } + } + + #[test] + fn test_pkarr_file_properties() { + // Basic test to verify the pkarr file + let pkarr_data = std::fs::read(PKARR_PATH) + .expect("Failed to read recovery.pkarr"); + + println!("PKARR file size: {} bytes", pkarr_data.len()); + assert_eq!(pkarr_data.len(), 91, "Expected pkarr file to be 91 bytes"); + + // The pkarr format typically starts with specific magic bytes + // This is just a basic sanity check + assert!(!pkarr_data.is_empty(), "PKARR file should not be empty"); + } +} \ No newline at end of file diff --git a/src/modules/paykit/mod.rs b/src/modules/paykit/mod.rs new file mode 100644 index 0000000..ec18065 --- /dev/null +++ b/src/modules/paykit/mod.rs @@ -0,0 +1,37 @@ +mod implementation; +mod types; +mod errors; +mod session_helper; +mod session_serialization; +mod deeplink_handler; + +pub use implementation::{ + PubkyAuthenticatedTransport, PubkyUnauthenticatedTransport, + set_payment_endpoint, remove_payment_endpoint, + get_payment_list, get_payment_endpoint, get_known_contacts, +}; +pub use types::{MethodId, EndpointData, PublicKey, SupportedPayments}; +pub use errors::PaykitError; +// Session helper exports - PKARR functions removed as Bitkit only receives tokens via deeplinks +// pub use session_helper::{SessionConfig, extract_public_key_from_pkarr, create_session_from_pkarr}; +pub use session_serialization::{ + SessionToken, + deserialize_token_to_session, + create_transport_from_session_token, +}; + +// Re-export for testing - these are needed by scanner tests +#[cfg(test)] +pub use session_serialization::create_session_token_from_keypair; +pub use deeplink_handler::{ + PaykitDeeplink, parse_paykit_deeplink, handle_paykit_deeplink, + create_pubky_ring_session_request, + // Not needed for Bitkit (only receives deeplinks, doesn't create them): + // create_deeplink_from_token, validate_paykit_deeplink, +}; + +#[cfg(test)] +mod tests; + +#[cfg(test)] +mod integration_tests; diff --git a/src/modules/paykit/recovery.pkarr b/src/modules/paykit/recovery.pkarr new file mode 100644 index 0000000..397b8d2 Binary files /dev/null and b/src/modules/paykit/recovery.pkarr differ diff --git a/src/modules/paykit/session_helper.rs b/src/modules/paykit/session_helper.rs new file mode 100644 index 0000000..3c32876 --- /dev/null +++ b/src/modules/paykit/session_helper.rs @@ -0,0 +1,291 @@ +//! Helper module for Pubky session management with pkarr files. +//! +//! This module provides utilities for creating authenticated sessions +//! from pkarr files for use with the Paykit module. + +use crate::paykit::errors::PaykitError; + +// #[cfg(feature = "pubky")] +// use paykit_lib::PublicKey as ExternalPublicKey; // Not used in current implementation + +/// Represents session configuration for pkarr-based authentication +pub struct SessionConfig { + /// Path to the pkarr file + pub pkarr_path: String, + /// Password for decrypting the pkarr file + pub password: String, + /// Optional homeserver URL (uses default if None) + pub homeserver_url: Option, +} + +impl SessionConfig { + /// Creates a new session configuration + pub fn new(pkarr_path: impl Into, password: impl Into) -> Self { + Self { + pkarr_path: pkarr_path.into(), + password: password.into(), + homeserver_url: None, + } + } + + /// Sets a custom homeserver URL + pub fn with_homeserver(mut self, url: impl Into) -> Self { + self.homeserver_url = Some(url.into()); + self + } +} + +/// Creates an authenticated Pubky session from a pkarr file. +/// +/// # Implementation Notes +/// +/// When the Pubky SDK is available, this function should: +/// +/// 1. **Load the pkarr file**: +/// ```ignore +/// let pkarr_bytes = std::fs::read(&config.pkarr_path)?; +/// ``` +/// +/// 2. **Decrypt and parse the pkarr**: +/// ```ignore +/// // The pkarr format contains an encrypted keypair +/// let keypair = pkarr::decrypt_keypair(&pkarr_bytes, &config.password)?; +/// // Or possibly: +/// let keypair = Keypair::from_pkarr(&pkarr_bytes, &config.password)?; +/// ``` +/// +/// 3. **Create a Pubky client/SDK instance**: +/// ```ignore +/// let client = PubkyClient::new()?; +/// // Or with custom homeserver: +/// let client = PubkyClient::with_homeserver(config.homeserver_url)?; +/// ``` +/// +/// 4. **Create a signer from the keypair**: +/// ```ignore +/// let signer = client.signer(keypair); +/// ``` +/// +/// 5. **Sign in or sign up**: +/// ```ignore +/// // Try to sign in first +/// let session = match signer.signin().await { +/// Ok(session) => session, +/// Err(_) => { +/// // If signin fails, try signup +/// let homeserver_pubkey = client.homeserver_pubkey().await?; +/// signer.signup(&homeserver_pubkey, None).await? +/// } +/// }; +/// ``` +/// +/// 6. **Return the authenticated transport**: +/// ```ignore +/// Ok(PubkyAuthenticatedTransport::new(session)) +/// ``` +#[cfg(feature = "pubky")] +pub async fn create_session_from_pkarr( + config: SessionConfig, +) -> Result { + // Verify the pkarr file exists + if !std::path::Path::new(&config.pkarr_path).exists() { + return Err(PaykitError::SessionError( + format!("PKARR file not found: {}", config.pkarr_path) + )); + } + + // Read the pkarr file + let pkarr_bytes = std::fs::read(&config.pkarr_path) + .map_err(|e| PaykitError::SessionError( + format!("Failed to read PKARR file: {}", e) + ))?; + + // Verify it's not empty + if pkarr_bytes.is_empty() { + return Err(PaykitError::SessionError( + "PKARR file is empty".to_string() + )); + } + + // Use the pubky API to decrypt the recovery file and create a session + use pubky::{recovery_file, Pubky}; + + // Decrypt the recovery file to get the keypair + let keypair = recovery_file::decrypt_recovery_file(&pkarr_bytes, &config.password) + .map_err(|e| PaykitError::SessionError( + format!("Failed to decrypt recovery file: {}", e) + ))?; + + // Create Pubky instance + let pubky = Pubky::new().map_err(|e| PaykitError::SessionError( + format!("Failed to create Pubky instance: {}", e) + ))?; + + // Create a signer from the keypair + let signer = pubky.signer(keypair); + + // Try to sign in first, then sign up if that fails + let session = match signer.signin().await { + Ok(session) => session, + Err(signin_err) => { + // If signin fails, try signup + // For signup, we need the homeserver's public key + // If homeserver_url is provided, use it; otherwise use default + if let Some(_homeserver_url) = config.homeserver_url { + // Parse the homeserver public key from URL if provided + // This is a simplified approach - in production you'd want better parsing + return Err(PaykitError::SessionError( + format!("Signin failed, signup not implemented yet: {}", signin_err) + )); + } else { + return Err(PaykitError::SessionError( + format!("Failed to sign in and no homeserver provided for signup: {}", signin_err) + )); + } + } + }; + + // Create authenticated transport from session + Ok(paykit_lib::PubkyAuthenticatedTransport::new(session)) +} + +/// Create session from pkarr stub when pubky feature is disabled +#[cfg(not(feature = "pubky"))] +pub async fn create_session_from_pkarr( + _config: SessionConfig, +) -> Result { + Err(PaykitError::SessionError( + "Session creation requires the 'pubky' feature to be enabled".to_string() + )) +} + +/// Extracts the public key from a pkarr file without creating a session. +/// +/// This is useful for read-only operations where you just need the public key. +#[cfg(feature = "pubky")] +pub fn extract_public_key_from_pkarr( + pkarr_path: &str, + password: &str, +) -> Result { + use pubky::recovery_file; + + // Verify the pkarr file exists + if !std::path::Path::new(pkarr_path).exists() { + return Err(PaykitError::SessionError( + format!("PKARR file not found: {}", pkarr_path) + )); + } + + let pkarr_bytes = std::fs::read(pkarr_path).map_err(|e| PaykitError::SessionError( + format!("Failed to read PKARR file: {}", e) + ))?; + + // Decrypt the recovery file to get the keypair + let keypair = recovery_file::decrypt_recovery_file(&pkarr_bytes, password) + .map_err(|e| PaykitError::SessionError( + format!("Failed to decrypt recovery file: {}", e) + ))?; + + // Get the public key from the keypair + let public_key = keypair.public_key(); + + Ok(public_key.to_string()) +} + +/// Extracts the public key from a pkarr file (stub for when pubky feature is disabled) +#[cfg(not(feature = "pubky"))] +pub fn extract_public_key_from_pkarr( + _pkarr_path: &str, + _password: &str, +) -> Result { + Err(PaykitError::SessionError( + "Public key extraction requires the 'pubky' feature to be enabled".to_string() + )) +} + +#[cfg(test)] +mod tests { + use super::*; + + const TEST_PKARR_PATH: &str = "src/modules/paykit/recovery.pkarr"; + const TEST_PASSWORD: &str = "password"; + + #[test] + fn test_session_config_creation() { + let config = SessionConfig::new(TEST_PKARR_PATH, TEST_PASSWORD); + assert_eq!(config.pkarr_path, TEST_PKARR_PATH); + assert_eq!(config.password, TEST_PASSWORD); + assert!(config.homeserver_url.is_none()); + + let config_with_server = SessionConfig::new(TEST_PKARR_PATH, TEST_PASSWORD) + .with_homeserver("https://homeserver.example.com"); + assert_eq!( + config_with_server.homeserver_url, + Some("https://homeserver.example.com".to_string()) + ); + } + + #[tokio::test] + async fn test_create_session_from_pkarr() { + let config = SessionConfig::new(TEST_PKARR_PATH, TEST_PASSWORD); + + // The pkarr file exists and should be readable + // Session creation may fail due to network issues (no homeserver available in tests) + // but should at least get past file reading and decryption + match create_session_from_pkarr(config).await { + Ok(session) => { + println!("Successfully created session (unexpected in test env without homeserver)"); + } + Err(PaykitError::SessionError(message)) => { + // Expected - session creation requires network access to homeserver + // Valid errors include: signin failures, network errors, etc. + println!("Session error (expected in test env): {}", message); + // Should NOT be a file not found error since the file exists + assert!(!message.contains("not found"), "File should exist"); + } + Err(e) => { + println!("Other error: {:?}", e); + } + } + } + + #[test] + fn test_extract_public_key_from_pkarr() { + match extract_public_key_from_pkarr(TEST_PKARR_PATH, TEST_PASSWORD) { + Ok(public_key) => { + println!("Extracted public key: {}", public_key); + assert!(!public_key.is_empty(), "Public key should not be empty"); + } + Err(PaykitError::SessionError(message)) => { + // May fail if pubky feature handles this differently + println!("Session error: {}", message); + // Should NOT be file not found + assert!(!message.contains("not found"), "File should exist"); + } + Err(e) => { + println!("Other error: {:?}", e); + } + } + } + + #[test] + fn test_pkarr_file_verification() { + // Test with non-existent file + let bad_config = SessionConfig::new("nonexistent.pkarr", "password"); + let result = create_session_from_pkarr(bad_config); + + // We can't use async in a sync test, so test the sync function + match extract_public_key_from_pkarr("nonexistent.pkarr", "password") { + Err(PaykitError::SessionError(message)) => { + assert!(message.contains("not found")); + } + _ => panic!("Expected file not found error"), + } + + // Test with actual file + assert!( + std::path::Path::new(TEST_PKARR_PATH).exists(), + "recovery.pkarr should exist" + ); + } +} \ No newline at end of file diff --git a/src/modules/paykit/session_serialization.rs b/src/modules/paykit/session_serialization.rs new file mode 100644 index 0000000..be18bc3 --- /dev/null +++ b/src/modules/paykit/session_serialization.rs @@ -0,0 +1,278 @@ +//! Session serialization module for passing Pubky sessions through deeplinks. +//! +//! This module provides utilities for converting authenticated sessions to/from +//! strings that can be passed through deeplinks or other communication channels. + +use crate::paykit::errors::PaykitError; +use crate::paykit::PubkyAuthenticatedTransport; +use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine}; +use serde::{Deserialize, Serialize}; + +/// Represents serializable session data that can be passed through a deeplink +#[derive(Debug, Clone, Serialize, Deserialize, uniffi::Record)] +pub struct SessionData { + /// The user's public key + pub public_key: String, + /// The user's secret key (encrypted or encoded) + pub secret_key: String, + /// Optional homeserver URL + pub homeserver_url: Option, + /// Session expiry timestamp (Unix timestamp) + pub expires_at: Option, + /// Additional metadata + pub metadata: Option, +} + +/// Represents a session token that can be passed through deeplinks +#[derive(Debug, Clone, uniffi::Record)] +pub struct SessionToken { + /// Base64 URL-safe encoded session data + pub token: String, +} + +impl SessionToken { + /// Creates a new session token from a string + pub fn new(token: impl Into) -> Self { + Self { + token: token.into(), + } + } + + /// Validates that the token is properly formatted + pub fn validate(&self) -> Result<(), PaykitError> { + // Check if it's valid base64 + URL_SAFE_NO_PAD + .decode(&self.token) + .map_err(|e| PaykitError::SessionError( + format!("Invalid session token encoding: {}", e) + ))?; + + Ok(()) + } +} + +/// Serializes session data into a token string suitable for deeplinks. +/// +/// # Security Considerations +/// - The secret key should be encrypted before serialization +/// - Use HTTPS/secure channels when transmitting +/// - Consider adding expiration times +/// - Implement token rotation for long-lived sessions +/// +/// # Example +/// ``` +/// let session_data = SessionData { +/// public_key: "user_public_key".to_string(), +/// secret_key: "encrypted_secret".to_string(), +/// homeserver_url: Some("https://homeserver.example".to_string()), +/// expires_at: Some(1234567890), +/// metadata: None, +/// }; +/// +/// let token = serialize_session_to_token(session_data)?; +/// // token.token can now be passed through a deeplink +/// ``` +#[uniffi::export] +pub fn serialize_session_to_token(session_data: SessionData) -> Result { + // Serialize the session data to JSON + let json = serde_json::to_string(&session_data).map_err(|e| PaykitError::SessionError( + format!("Failed to serialize session data: {}", e) + ))?; + + // Encode as base64 URL-safe (no padding) for deeplink compatibility + let encoded = URL_SAFE_NO_PAD.encode(json.as_bytes()); + + Ok(SessionToken::new(encoded)) +} + +/// Deserializes a session token back into session data. +/// +/// # Example +/// ``` +/// let token = SessionToken::new("base64_encoded_session_data"); +/// let session_data = deserialize_token_to_session(token)?; +/// // Now you have the session data back +/// ``` +#[uniffi::export] +pub fn deserialize_token_to_session(token: SessionToken) -> Result { + // Validate the token first + token.validate()?; + + // Decode from base64 + let decoded = URL_SAFE_NO_PAD + .decode(&token.token) + .map_err(|e| PaykitError::SessionError( + format!("Failed to decode session token: {}", e) + ))?; + + // Parse JSON + let session_data: SessionData = + serde_json::from_slice(&decoded).map_err(|e| PaykitError::SessionError( + format!("Failed to parse session data: {}", e) + ))?; + + Ok(session_data) +} + +/// Creates an authenticated transport from a session token received via deeplink. +/// +/// This is the main entry point for reconstructing a session from a deeplink. +/// +/// # Flow +/// 1. App receives deeplink with session token +/// 2. Extract token from deeplink URL +/// 3. Call this function to create authenticated transport +/// 4. Use transport for paykit operations +/// +/// # Example Deeplink Format +/// ``` +/// myapp://paykit/session?token=eyJwdWJsaWNfa2V5IjoiLi4uIiwic2VjcmV0X2tleSI6Ii4uLiJ9 +/// ``` +#[cfg(feature = "pubky")] +pub async fn create_transport_from_session_token( + token: SessionToken, +) -> Result { + use paykit_lib::PubkyAuthenticatedTransport as ExternalTransport; + use pubky::{Keypair, Pubky}; + + // Deserialize the session data + let session_data = deserialize_token_to_session(token)?; + + // Check expiration if present + if let Some(expires_at) = session_data.expires_at { + let now = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .map_err(|e| PaykitError::SessionError(format!("System time error: {}", e)))? + .as_secs() as i64; + + if now > expires_at { + return Err(PaykitError::SessionError("Session token has expired".to_string())); + } + } + + // Create Pubky instance + let pubky = Pubky::new().map_err(|e| PaykitError::SessionError( + format!("Failed to create Pubky instance: {}", e) + ))?; + + // Reconstruct the keypair from the session data + // Decode the secret key from hex or base64 + let secret_key_bytes = hex::decode(&session_data.secret_key) + .or_else(|_| base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(&session_data.secret_key)) + .map_err(|e| PaykitError::SessionError(format!("Failed to decode secret key: {}", e)))?; + + // Create keypair from the secret key bytes + // Note: from_secret_key expects a 32-byte array + if secret_key_bytes.len() != 32 { + return Err(PaykitError::SessionError( + format!("Invalid secret key length: expected 32 bytes, got {}", secret_key_bytes.len()) + )); + } + let mut secret_key_array = [0u8; 32]; + secret_key_array.copy_from_slice(&secret_key_bytes); + + let keypair = Keypair::from_secret_key(&secret_key_array); + + // Create signer with the keypair + let signer = pubky.signer(keypair); + + // Sign in to create a session + let session = signer.signin().await.map_err(|e| PaykitError::SessionError( + format!("Failed to sign in: {}", e) + ))?; + + // Create authenticated transport from session + Ok(ExternalTransport::new(session).into()) +} + +/// Creates an authenticated transport from a session token (non-pubky stub) +#[cfg(not(feature = "pubky"))] +pub async fn create_transport_from_session_token( + _token: SessionToken, +) -> Result { + Err(PaykitError::SessionError( + "Session creation requires the 'pubky' feature to be enabled".to_string() + )) +} + +/// Helper function to create a session token from raw keypair data. +/// +/// This is useful when you have the keypair but need to create a shareable token. +#[uniffi::export] +pub fn create_session_token_from_keypair( + public_key: String, + secret_key: String, + homeserver_url: Option, + expires_in_seconds: Option, +) -> Result { + let expires_at = expires_in_seconds.map(|seconds| { + let now = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs() as i64; + now + seconds + }); + + let session_data = SessionData { + public_key, + secret_key, + homeserver_url, + expires_at, + metadata: None, + }; + + serialize_session_to_token(session_data) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_session_token_serialization_roundtrip() { + let session_data = SessionData { + public_key: "test_public_key_123".to_string(), + secret_key: "test_secret_key_456".to_string(), + homeserver_url: Some("https://example.com".to_string()), + expires_at: Some(1234567890), + metadata: Some("test_metadata".to_string()), + }; + + // Serialize to token + let token = serialize_session_to_token(session_data.clone()).unwrap(); + assert!(!token.token.is_empty()); + + // Deserialize back + let deserialized = deserialize_token_to_session(token).unwrap(); + assert_eq!(deserialized.public_key, session_data.public_key); + assert_eq!(deserialized.secret_key, session_data.secret_key); + assert_eq!(deserialized.homeserver_url, session_data.homeserver_url); + assert_eq!(deserialized.expires_at, session_data.expires_at); + assert_eq!(deserialized.metadata, session_data.metadata); + } + + #[test] + fn test_session_token_validation() { + // Valid token + let valid_token = SessionToken::new("eyJwdWJsaWNfa2V5IjoidGVzdCJ9"); + assert!(valid_token.validate().is_ok()); + + // Invalid token (not base64) + let invalid_token = SessionToken::new("not-base64!@#$%"); + assert!(invalid_token.validate().is_err()); + } + + #[test] + fn test_create_token_with_expiration() { + let token = create_session_token_from_keypair( + "public_key".to_string(), + "secret_key".to_string(), + None, + Some(3600), // 1 hour + ) + .unwrap(); + + let session_data = deserialize_token_to_session(token).unwrap(); + assert!(session_data.expires_at.is_some()); + } +} \ No newline at end of file diff --git a/src/modules/paykit/tests.rs b/src/modules/paykit/tests.rs new file mode 100644 index 0000000..f97d6c8 --- /dev/null +++ b/src/modules/paykit/tests.rs @@ -0,0 +1,149 @@ +#[cfg(test)] +mod tests { + use crate::paykit::*; + + // ===== Error Tests ===== + + #[test] + fn test_error_conversions() { + // Test Transport error + let transport_err = PaykitError::Transport("Connection failed".to_string()); + assert_eq!( + format!("{}", transport_err), + "Transport error: Connection failed" + ); + + // Test InvalidPublicKey error + let pk_err = PaykitError::InvalidPublicKey("Invalid format".to_string()); + assert_eq!( + format!("{}", pk_err), + "Invalid public key: Invalid format" + ); + + // Test SessionError + let session_err = PaykitError::SessionError("Session expired".to_string()); + assert_eq!( + format!("{}", session_err), + "Session error: Session expired" + ); + } + + // ===== Type Tests ===== + + #[test] + fn test_method_id_constants() { + assert_eq!(MethodId::LIGHTNING, "lightning"); + assert_eq!(MethodId::ONCHAIN, "onchain"); + assert_eq!(MethodId::BOLT11, "bolt11"); + assert_eq!(MethodId::BOLT12, "bolt12"); + assert_eq!(MethodId::LNURL, "lnurl"); + } + + #[test] + fn test_method_id_creation() { + let method1 = MethodId::lightning(); + assert_eq!(method1.id, "lightning"); + + let method2 = MethodId::new("custom"); + assert_eq!(method2.id, "custom"); + + let method3 = MethodId::new(String::from("string_method")); + assert_eq!(method3.id, "string_method"); + } + + #[test] + fn test_public_key_creation() { + let key1 = PublicKey::new("test_key"); + assert_eq!(key1.key, "test_key"); + + let key2 = PublicKey::new(String::from("string_key")); + assert_eq!(key2.key, "string_key"); + } + + #[test] + fn test_public_key_validation_edge_cases() { + // Test minimum valid length (32 chars) + let min_valid = PublicKey::new("a".repeat(32)); + assert!(min_valid.validate().is_ok()); + + // Test maximum valid length (256 chars) + let max_valid = PublicKey::new("a".repeat(256)); + assert!(max_valid.validate().is_ok()); + + // Test just below minimum + let below_min = PublicKey::new("a".repeat(31)); + assert!(below_min.validate().is_err()); + + // Test just above maximum + let above_max = PublicKey::new("a".repeat(257)); + assert!(above_max.validate().is_err()); + } + + // ===== Transport Tests ===== + + #[test] + fn test_unauthenticated_transport_creation() { + // This test will fail in CI without a Pubky network, but demonstrates the API + let result = PubkyUnauthenticatedTransport::new(); + // We expect this to either succeed or fail with a transport error, not unimplemented + match result { + Ok(_) => println!("Successfully created unauthenticated transport"), + Err(PaykitError::Transport(..)) => { + println!("Transport error (expected in test environment)") + } + Err(e) => panic!("Unexpected error type: {:?}", e), + } + } + + #[test] + fn test_authenticated_transport_creation() { + // Test that direct creation returns appropriate error + let result = PubkyAuthenticatedTransport::new(); + + assert!(result.is_err()); + match result { + Err(PaykitError::SessionError(message)) => { + assert!(message.contains("Direct session creation not supported")); + } + _ => panic!("Expected SessionError"), + } + } + + #[test] + fn test_error_display_formatting() { + let errors = vec![ + PaykitError::Unimplemented("Feature X".to_string()), + PaykitError::Transport("Connection timeout".to_string()), + PaykitError::InvalidPublicKey("Invalid hex format".to_string()), + PaykitError::InvalidMethodId("Empty method ID".to_string()), + PaykitError::InvalidEndpointData("Invalid JSON".to_string()), + PaykitError::SessionError("Not authenticated".to_string()), + ]; + + for error in errors { + let formatted = format!("{}", error); + assert!(!formatted.is_empty()); + println!("Error format: {}", formatted); + } + } + + #[test] + fn test_public_key_string_conversions() { + let original = "test_public_key_string_123456789012345678901234567890"; + + // Test FromStr + let from_str: Result = original.parse(); + assert!(from_str.is_ok()); + let key = from_str.unwrap(); + assert_eq!(key.key, original); + + // Test Display + let displayed = format!("{}", key); + assert_eq!(displayed, original); + + // Round trip + let round_trip: Result = displayed.parse(); + assert!(round_trip.is_ok()); + assert_eq!(round_trip.unwrap().key, original); + } +} diff --git a/src/modules/paykit/types.rs b/src/modules/paykit/types.rs new file mode 100644 index 0000000..68f648e --- /dev/null +++ b/src/modules/paykit/types.rs @@ -0,0 +1,284 @@ +use paykit_lib::{ + EndpointData as ExternalEndpointData, MethodId as ExternalMethodId, + PublicKey as ExternalPublicKey, SupportedPayments as ExternalSupportedPayments, +}; +use std::collections::HashMap; +use std::fmt; +use std::str::FromStr; + +/// Identifier for a payment method specification (e.g., "lightning", "onchain", "bolt11"). +#[derive(Clone, Debug, PartialEq, Eq, Hash, uniffi::Record)] +pub struct MethodId { + pub id: String, +} + +impl MethodId { + /// Common payment method constant for Lightning Network + pub const LIGHTNING: &'static str = "lightning"; + /// Common payment method constant for on-chain Bitcoin + pub const ONCHAIN: &'static str = "onchain"; + /// Common payment method constant for BOLT11 invoices + pub const BOLT11: &'static str = "bolt11"; + /// Common payment method constant for BOLT12 offers + pub const BOLT12: &'static str = "bolt12"; + /// Common payment method constant for LNURL + pub const LNURL: &'static str = "lnurl"; + + /// Creates a new MethodId from a string + pub fn new(id: impl Into) -> Self { + Self { id: id.into() } + } + + /// Creates a Lightning method ID + pub fn lightning() -> Self { + Self::new(Self::LIGHTNING) + } + + /// Creates an on-chain method ID + pub fn onchain() -> Self { + Self::new(Self::ONCHAIN) + } +} + +impl From for ExternalMethodId { + fn from(value: MethodId) -> Self { + ExternalMethodId(value.id) + } +} + +impl From for MethodId { + fn from(value: ExternalMethodId) -> Self { + MethodId { id: value.0 } + } +} + +/// Serialized payload served by a payment endpoint (UTF-8 text such as JSON, LNURL, etc.). +#[derive(Clone, Debug, PartialEq, Eq, uniffi::Record)] +pub struct EndpointData { + pub data: String, +} + +impl From for ExternalEndpointData { + fn from(value: EndpointData) -> Self { + ExternalEndpointData(value.data) + } +} + +impl From for EndpointData { + fn from(value: ExternalEndpointData) -> Self { + EndpointData { data: value.0 } + } +} + +/// Public key wrapper for Paykit operations. +#[derive(Clone, Debug, PartialEq, Eq, Hash, uniffi::Record)] +pub struct PublicKey { + pub key: String, +} + +impl PublicKey { + /// Creates a new PublicKey from a string + pub fn new(key: impl Into) -> Self { + Self { key: key.into() } + } + + /// Validates the public key format + pub fn validate(&self) -> Result<(), String> { + // Basic validation - ensure it's not empty and has reasonable length + if self.key.is_empty() { + return Err("Public key cannot be empty".to_string()); + } + if self.key.len() < 32 || self.key.len() > 256 { + return Err("Public key has invalid length".to_string()); + } + // Additional validation can be added here for specific key formats + Ok(()) + } +} + +impl fmt::Display for PublicKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.key) + } +} + +impl FromStr for PublicKey { + type Err = String; + + fn from_str(s: &str) -> Result { + let key = PublicKey::new(s); + key.validate()?; + Ok(key) + } +} + +impl TryFrom for ExternalPublicKey { + type Error = String; + + fn try_from(value: PublicKey) -> Result { + // When using pubky feature, parse the string representation + // The pubky crate's PublicKey type has a FromStr implementation + value.key + .parse::() + .map_err(|e| format!("Failed to parse public key: {}", e)) + } +} + +impl From for PublicKey { + fn from(value: ExternalPublicKey) -> Self { + PublicKey { + key: value.to_string(), + } + } +} + +/// Collection of supported payment entries keyed by method identifiers. +#[derive(Clone, Debug, PartialEq, Eq, uniffi::Record)] +pub struct SupportedPayments { + pub entries: HashMap, +} + +impl From for ExternalSupportedPayments { + fn from(value: SupportedPayments) -> Self { + let entries = value + .entries + .into_iter() + .map(|(k, v)| (ExternalMethodId(k), v.into())) + .collect(); + ExternalSupportedPayments { entries } + } +} + +impl From for SupportedPayments { + fn from(value: ExternalSupportedPayments) -> Self { + let entries = value + .entries + .into_iter() + .map(|(k, v)| (k.0, v.into())) + .collect(); + SupportedPayments { entries } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_method_id_conversion() { + let method = MethodId { + id: "lightning".to_string(), + }; + let external: ExternalMethodId = method.clone().into(); + assert_eq!(external.0, "lightning"); + + let back: MethodId = external.into(); + assert_eq!(back, method); + } + + #[test] + fn test_method_id_helpers() { + let lightning = MethodId::lightning(); + assert_eq!(lightning.id, "lightning"); + + let onchain = MethodId::onchain(); + assert_eq!(onchain.id, "onchain"); + + let custom = MethodId::new("custom_method"); + assert_eq!(custom.id, "custom_method"); + } + + #[test] + fn test_endpoint_data_conversion() { + let data = EndpointData { + data: r#"{"bolt11":"lnbc..."}"#.to_string(), + }; + let external: ExternalEndpointData = data.clone().into(); + assert_eq!(external.0, r#"{"bolt11":"lnbc..."}"#); + + let back: EndpointData = external.into(); + assert_eq!(back, data); + } + + #[test] + fn test_public_key_validation() { + let valid_key = PublicKey::new("a".repeat(64)); + assert!(valid_key.validate().is_ok()); + + let empty_key = PublicKey::new(""); + assert!(empty_key.validate().is_err()); + + let short_key = PublicKey::new("abc"); + assert!(short_key.validate().is_err()); + + let long_key = PublicKey::new("a".repeat(300)); + assert!(long_key.validate().is_err()); + } + + #[test] + fn test_public_key_display() { + let key = PublicKey::new("test_public_key_123"); + assert_eq!(format!("{}", key), "test_public_key_123"); + } + + #[test] + fn test_public_key_from_str() { + let key_str = "a".repeat(64); + let key: Result = key_str.parse(); + assert!(key.is_ok()); + assert_eq!(key.unwrap().key, key_str); + + let invalid_key: Result = "".parse(); + assert!(invalid_key.is_err()); + } + + #[test] + fn test_supported_payments_conversion() { + let mut entries = HashMap::new(); + entries.insert( + "lightning".to_string(), + EndpointData { + data: r#"{"bolt11":"lnbc..."}"#.to_string(), + }, + ); + + let payments = SupportedPayments { entries }; + let external: ExternalSupportedPayments = payments.clone().into(); + assert_eq!(external.entries.len(), 1); + + let back: SupportedPayments = external.into(); + assert_eq!(back, payments); + } + + #[test] + fn test_multiple_payment_methods() { + let mut entries = HashMap::new(); + entries.insert( + MethodId::LIGHTNING.to_string(), + EndpointData { + data: r#"{"bolt11":"lnbc..."}"#.to_string(), + }, + ); + entries.insert( + MethodId::ONCHAIN.to_string(), + EndpointData { + data: r#"{"address":"bc1..."}"#.to_string(), + }, + ); + entries.insert( + MethodId::LNURL.to_string(), + EndpointData { + data: r#"{"lnurl":"lnurl1..."}"#.to_string(), + }, + ); + + let payments = SupportedPayments { entries }; + assert_eq!(payments.entries.len(), 3); + + let external: ExternalSupportedPayments = payments.clone().into(); + assert_eq!(external.entries.len(), 3); + + let back: SupportedPayments = external.into(); + assert_eq!(back.entries.len(), 3); + } +} diff --git a/src/modules/scanner/implementation.rs b/src/modules/scanner/implementation.rs index a65d472..69f8084 100644 --- a/src/modules/scanner/implementation.rs +++ b/src/modules/scanner/implementation.rs @@ -47,7 +47,12 @@ impl Scanner { // Handle Bitkit deep links if invoice_str.starts_with("bitkit://") { let data = invoice_str.replace("bitkit://", ""); - + + // Check if it's a paykit session deeplink: bitkit://paykit/... + if data.starts_with("paykit/") { + return Self::decode_paykit_deeplink(invoice_str); + } + // Check if it's a gift code format: bitkit://gift-- if data.starts_with("gift-") { let parts: Vec<&str> = data.splitn(3, '-').collect(); @@ -65,6 +70,11 @@ impl Scanner { return Box::pin(Self::decode(data)).await; } + // Handle generic paykit deeplinks (any scheme with /paykit/ path) + if Self::is_paykit_deeplink(invoice_str) { + return Self::decode_paykit_deeplink(invoice_str); + } + // Node connection string handling if invoice_str.contains('@') { let parts: Vec<&str> = invoice_str.split(':').collect(); @@ -271,6 +281,70 @@ impl Scanner { }) } + /// Checks if a string is a paykit deeplink + /// + /// Only accepts known/supported URL schemes to avoid ambiguity with + /// different transports (e.g., iroh:// vs pubky://). + fn is_paykit_deeplink(url: &str) -> bool { + // Parse URL to check scheme and structure + if let Ok(parsed) = Url::parse(url) { + let scheme = parsed.scheme(); + + // Check for paykit:// scheme directly + if scheme == "paykit" { + return true; + } + + // Only accept known schemes with /paykit/ path + let known_schemes = ["bitkit", "pubky", "http", "https"]; + if !known_schemes.contains(&scheme) { + return false; + } + + // For custom schemes, check if host is "paykit" + if let Some(host) = parsed.host_str() { + if host == "paykit" { + return true; + } + } + + // For http(s), check if path contains /paykit/ + if scheme == "http" || scheme == "https" { + return parsed.path().contains("/paykit/"); + } + } + + false + } + + /// Decodes a paykit deeplink into Scanner data + fn decode_paykit_deeplink(url: &str) -> Result { + use crate::paykit::{parse_paykit_deeplink, PaykitError}; + + // Try to parse the deeplink + let deeplink = match parse_paykit_deeplink(url.to_string()) { + Ok(dl) => dl, + Err(PaykitError::SessionError(_message)) => { + return Err(DecodingError::InvalidFormat); + } + Err(_) => { + return Err(DecodingError::InvalidFormat); + } + }; + + // Extract the session token + let token = deeplink.session_token.ok_or(DecodingError::InvalidFormat)?; + + Ok(Scanner::PaykitSession { + data: ScannedPaykitSession { + url: url.to_string(), + action: deeplink.action, + token, + parameters: deeplink.parameters, + } + }) + } + fn handle_node_id(invoice_str: &str) -> Result { Ok(Scanner::NodeId { url: invoice_str.to_string(), diff --git a/src/modules/scanner/tests.rs b/src/modules/scanner/tests.rs index 9da02a6..020afad 100644 --- a/src/modules/scanner/tests.rs +++ b/src/modules/scanner/tests.rs @@ -56,4 +56,173 @@ mod tests { let invoice = "lnbc1invalid".to_string(); assert!(matches!(Scanner::decode(invoice).await, Err(DecodingError::InvalidFormat))); } + + #[tokio::test] + async fn test_paykit_deeplink_with_bitkit_scheme() { + use crate::paykit::create_session_token_from_keypair; + + // Create a valid token + let token = create_session_token_from_keypair( + "test_public_key".to_string(), + "test_secret_key".to_string(), + None, + Some(300), + ).unwrap(); + + // Create deeplink with bitkit:// scheme + let deeplink = format!("bitkit://paykit/session?token={}", token.token); + let decoded = Scanner::decode(deeplink.clone()).await.unwrap(); + + match decoded { + Scanner::PaykitSession { data } => { + assert_eq!(data.url, deeplink); + assert_eq!(data.action, "session"); + assert_eq!(data.token, token.token); + assert!(data.parameters.is_empty()); + } + _ => panic!("Should be a PaykitSession"), + } + } + + #[tokio::test] + async fn test_paykit_deeplink_with_pubky_scheme() { + use crate::paykit::create_session_token_from_keypair; + + // Create a valid token + let token = create_session_token_from_keypair( + "test_public_key".to_string(), + "test_secret_key".to_string(), + None, + Some(300), + ).unwrap(); + + // Create deeplink with pubky:// scheme (a known/supported scheme) + let deeplink = format!("pubky://paykit/connect?token={}&return_url=home", token.token); + let decoded = Scanner::decode(deeplink.clone()).await.unwrap(); + + match decoded { + Scanner::PaykitSession { data } => { + assert_eq!(data.url, deeplink); + assert_eq!(data.action, "connect"); + assert_eq!(data.token, token.token); + assert_eq!(data.parameters.get("return_url").unwrap(), "home"); + } + _ => panic!("Should be a PaykitSession"), + } + } + + #[tokio::test] + async fn test_paykit_deeplink_with_paykit_scheme() { + use crate::paykit::create_session_token_from_keypair; + + // Create a valid token + let token = create_session_token_from_keypair( + "test_public_key".to_string(), + "test_secret_key".to_string(), + None, + Some(300), + ).unwrap(); + + // Create deeplink with paykit:// scheme directly + let deeplink = format!("paykit://session?token={}", token.token); + let decoded = Scanner::decode(deeplink.clone()).await.unwrap(); + + match decoded { + Scanner::PaykitSession { data } => { + assert_eq!(data.url, deeplink); + assert_eq!(data.action, "session"); + assert_eq!(data.token, token.token); + } + _ => panic!("Should be a PaykitSession"), + } + } + + #[tokio::test] + async fn test_unknown_scheme_not_recognized_as_paykit() { + // Unknown schemes should not be recognized as paykit deeplinks + // This prevents ambiguity with different transports (e.g., iroh://) + let unknown_scheme = "iroh://paykit/session?token=abc123"; + let result = Scanner::decode(unknown_scheme.to_string()).await; + + // Should fail or not be recognized as PaykitSession + match result { + Ok(Scanner::PaykitSession { .. }) => { + panic!("Unknown scheme should not be recognized as PaykitSession"); + } + _ => { + // Expected - either error or different scanner type + } + } + } + + #[tokio::test] + async fn test_paykit_deeplink_with_https() { + use crate::paykit::create_session_token_from_keypair; + + // Create a valid token + let token = create_session_token_from_keypair( + "test_public_key".to_string(), + "test_secret_key".to_string(), + Some("https://homeserver.example".to_string()), + None, + ).unwrap(); + + // Create HTTPS deeplink + let deeplink = format!("https://app.example.com/paykit/session?token={}", token.token); + let decoded = Scanner::decode(deeplink.clone()).await.unwrap(); + + match decoded { + Scanner::PaykitSession { data } => { + assert_eq!(data.url, deeplink); + assert_eq!(data.action, "session"); + assert_eq!(data.token, token.token); + } + _ => panic!("Should be a PaykitSession"), + } + } + + #[tokio::test] + async fn test_invalid_paykit_deeplink() { + // Test with missing token (using a known scheme) + let invalid_deeplink = "bitkit://paykit/session"; + let result = Scanner::decode(invalid_deeplink.to_string()).await; + assert!(result.is_err(), "Should fail with missing token"); + + // Test with completely invalid token (not base64) using a known scheme + let invalid_token = "bitkit://paykit/session?token=!!!invalid!!!"; + let result = Scanner::decode(invalid_token.to_string()).await; + // Should parse URL but fail on token validation in actual usage + // Scanner itself just extracts the data, validation happens later + match result { + Ok(Scanner::PaykitSession { data }) => { + // Scanner extracts it, but token is invalid + assert!(data.token.contains("!!!")); + } + _ => panic!("Should parse as PaykitSession even with invalid token"), + } + } + + #[tokio::test] + async fn test_paykit_deeplink_priority() { + // Ensure paykit deeplinks are recognized before other formats + use crate::paykit::create_session_token_from_keypair; + + let token = create_session_token_from_keypair( + "key".to_string(), + "secret".to_string(), + None, + None, + ).unwrap(); + + // Test that bitkit://paykit/... is handled as paykit, not generic bitkit + let deeplink = format!("bitkit://paykit/session?token={}", token.token); + let decoded = Scanner::decode(deeplink.clone()).await.unwrap(); + + match decoded { + Scanner::PaykitSession { .. } => { + // Success - handled as paykit + } + _ => panic!("bitkit://paykit/ should be handled as PaykitSession"), + } + } } \ No newline at end of file diff --git a/src/modules/scanner/types.rs b/src/modules/scanner/types.rs index 783ab3a..f4ccdce 100644 --- a/src/modules/scanner/types.rs +++ b/src/modules/scanner/types.rs @@ -96,6 +96,14 @@ pub struct PubkyAuth { pub data: String, } +#[derive(uniffi::Record, Serialize, Debug, Clone)] +pub struct ScannedPaykitSession { + pub url: String, + pub action: String, + pub token: String, + pub parameters: HashMap, +} + #[derive(uniffi::Record, Serialize, Debug, Clone)] pub struct OnChainInvoice { pub address: String, @@ -123,6 +131,7 @@ pub enum Scanner { OnChain { invoice: OnChainInvoice }, Lightning { invoice: LightningInvoice }, PubkyAuth { data: String }, + PaykitSession { data: ScannedPaykitSession }, LnurlChannel { data: LnurlChannelData }, LnurlAuth { data: LnurlAuthData }, LnurlWithdraw { data: LnurlWithdrawData },