diff --git a/.gitmodules b/.gitmodules index df6a776..e4eb6ef 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "kinode-wit"] path = kinode-wit url = https://github.com/uqbar-dao/kinode-wit.git - branch = master + branch = v0.8 diff --git a/Cargo.lock b/Cargo.lock index 93c16ab..088658b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,9 +68,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.7.0" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99bbad0a6b588ef4aec1b5ddbbfdacd9ef04e00b979617765b03174318ee1f3a" +checksum = "db8aa973e647ec336810a9356af8aea787249c9d00b1525359f3db29a68d231b" dependencies = [ "alloy-rlp", "bytes", @@ -107,7 +107,7 @@ checksum = "1a047897373be4bbb0224c1afdabca92648dc57a9c9ef6e7b0be3aff7a859c83" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.64", ] [[package]] @@ -140,9 +140,23 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.7.0" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "452d929748ac948a10481fff4123affead32c553cf362841c5103dd508bdfc16" +checksum = "7dbd17d67f3e89478c8a634416358e539e577899666c927bc3d2b1328ee9b6ca" +dependencies = [ + "alloy-sol-macro-expander", + "alloy-sol-macro-input", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.64", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6da95adcf4760bb4b108fefa51d50096c5e5fdd29ee72fed3e86ee414f2e34" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -151,31 +165,31 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.64", "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.7.0" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df64e094f6d2099339f9e82b5b38440b159757b6920878f28316243f8166c8d1" +checksum = "32c8da04c1343871fb6ce5a489218f9c85323c8340a36e9106b5fc98d4dd59d5" dependencies = [ "const-hex", "dunce", "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.64", "syn-solidity", ] [[package]] name = "alloy-sol-types" -version = "0.7.0" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43bc2d6dfc2a19fd56644494479510f98b1ee929e04cf0d4aa45e98baa3e545b" +checksum = "40a64d2d2395c1ac636b62419a7b17ec39031d6b2367e66e9acbf566e6055e9c" dependencies = [ "alloy-primitives", "alloy-sol-macro", @@ -202,9 +216,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "27a4bd113ab6da4cd0f521068a6e2ee1065eab54107266a11835d02c8ec86a37" [[package]] name = "ark-ff" @@ -338,26 +352,26 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "auto_impl" -version = "1.1.2" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "823b8bb275161044e2ac7a25879cb3e2480cb403e3943022c7c769c599b756aa" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.64", ] [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -376,9 +390,9 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" @@ -412,9 +426,9 @@ checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bitvec" @@ -451,9 +465,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-slice-cast" @@ -469,18 +483,18 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" dependencies = [ "serde", ] [[package]] name = "c-kzg" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3130f3d8717cc02e668a896af24984d5d5d4e8bf12e278e982e0f1bd88a0f9af" +checksum = "cdf100c4cea8f207e883ff91ca886d621d8a166cb04971dfaa9bb8fd99ed95df" dependencies = [ "blst", "cc", @@ -492,12 +506,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" [[package]] name = "cfg-if" @@ -507,9 +518,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "const-hex" -version = "1.10.0" +version = "1.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" +checksum = "70ff96486ccc291d36a958107caf2c0af8c78c0af7d31ae2f35ce055130de1a6" dependencies = [ "cfg-if", "cpufeatures", @@ -569,9 +580,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "zeroize", @@ -644,9 +655,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "elliptic-curve" @@ -675,9 +686,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys", @@ -685,9 +696,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fastrlp" @@ -757,7 +768,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.64", ] [[package]] @@ -799,9 +810,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -833,9 +844,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" @@ -884,9 +895,9 @@ dependencies = [ [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -931,9 +942,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.2" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown", @@ -960,15 +971,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -988,9 +999,9 @@ dependencies = [ [[package]] name = "keccak-asm" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb8515fff80ed850aea4a1595f2e519c003e2a00a82fe168ebf5269196caf444" +checksum = "47a3633291834c4fbebf8673acbc1b04ec9d151418ff9b8e26dcd79129928758" dependencies = [ "digest 0.10.7", "sha3-asm", @@ -998,7 +1009,7 @@ dependencies = [ [[package]] name = "kinode_process_lib" -version = "0.7.1" +version = "0.8.0" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -1031,9 +1042,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libm" @@ -1043,21 +1054,21 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "mime" @@ -1077,39 +1088,37 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ "adler", ] [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" dependencies = [ - "autocfg", "num-integer", "num-traits", ] [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -1142,9 +1151,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "parity-scale-codec" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec", "bitvec", @@ -1156,9 +1165,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1168,9 +1177,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "percent-encoding" @@ -1180,9 +1189,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.7" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" dependencies = [ "memchr", "thiserror", @@ -1191,29 +1200,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.64", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1250,11 +1259,10 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.2" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_datetime", "toml_edit", ] @@ -1284,9 +1292,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -1319,9 +1327,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -1373,9 +1381,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "rfc6979" @@ -1399,9 +1407,9 @@ dependencies = [ [[package]] name = "rmp" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20" +checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" dependencies = [ "byteorder", "num-traits", @@ -1410,9 +1418,9 @@ dependencies = [ [[package]] name = "rmp-serde" -version = "1.1.2" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a" +checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" dependencies = [ "byteorder", "rmp", @@ -1421,9 +1429,9 @@ dependencies = [ [[package]] name = "ruint" -version = "1.11.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825" +checksum = "8f308135fef9fc398342da5472ce7c484529df23743fb7c734e0f3d472971e62" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", @@ -1445,15 +1453,15 @@ dependencies = [ [[package]] name = "ruint-macro" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" +checksum = "f86854cf50259291520509879a5c294c3c9a4c334e9ff65071c51e42ef1e2343" [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hex" @@ -1476,14 +1484,14 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.21", + "semver 1.0.23", ] [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags", "errno", @@ -1506,9 +1514,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "sec1" @@ -1535,9 +1543,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "semver-parser" @@ -1550,29 +1558,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.196" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.64", ] [[package]] name = "serde_json" -version = "1.0.113" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -1592,9 +1600,9 @@ dependencies = [ [[package]] name = "sha3-asm" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac61da6b35ad76b195eb4771210f947734321a8d81d7738e1580d953bc7a15e" +checksum = "a9b57fd861253bff08bb1919e995f90ba8f4889de2726091c8876f3a4e823b40" dependencies = [ "cc", "cfg-if", @@ -1621,15 +1629,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "spdx" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bde1398b09b9f93fc2fc9b9da86e362693e999d3a54a8ac47a99a5a73f638b" +checksum = "29ef1a0fa1e39ac22972c8db23ff89aea700ab96aa87114e1fb55937a631a0c9" dependencies = [ "smallvec", ] @@ -1669,9 +1677,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "7ad3dee41f36859875573074334c200d1add8e4a87bb37113ebd31d926b7b11f" dependencies = [ "proc-macro2", "quote", @@ -1680,14 +1688,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.7.0" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4497156948bd342b52038035a6fa514a89626e37af9d2c52a5e8d8ebcc7ee479" +checksum = "b8db114c44cf843a8bacd37a146e37987a0b823a0e8bc4fdc610c9c72ab397a5" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.64", ] [[package]] @@ -1698,9 +1706,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.10.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", @@ -1710,22 +1718,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.64", ] [[package]] @@ -1763,9 +1771,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "pin-project-lite", @@ -1773,15 +1781,15 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ "indexmap", "toml_datetime", @@ -1835,7 +1843,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.64", ] [[package]] @@ -1900,18 +1908,18 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-xid" @@ -1959,9 +1967,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1969,24 +1977,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.64", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.40" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -1996,9 +2004,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2006,22 +2014,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.64", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasm-encoder" @@ -2056,14 +2064,14 @@ checksum = "d6998515d3cf3f8b980ef7c11b29a9b1017d4cf86b99ae93b546992df9931413" dependencies = [ "bitflags", "indexmap", - "semver 1.0.21", + "semver 1.0.23", ] [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -2080,13 +2088,14 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", + "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", @@ -2095,51 +2104,57 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" -version = "0.5.37" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cad8365489051ae9f054164e459304af2e7e9bb407c958076c8bf4aef52da5" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] @@ -2196,7 +2211,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.64", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -2230,7 +2245,7 @@ dependencies = [ "id-arena", "indexmap", "log", - "semver 1.0.21", + "semver 1.0.23", "serde", "serde_derive", "serde_json", @@ -2264,5 +2279,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.64", ] diff --git a/Cargo.toml b/Cargo.toml index f5e8181..d4efde3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kinode_process_lib" description = "A library for writing Kinode processes in Rust." -version = "0.7.1" +version = "0.8.0" edition = "2021" license-file = "LICENSE" homepage = "https://kinode.org" diff --git a/README.md b/README.md index a5c4015..601bf71 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ Library of functions for more ergonomic kinode process development. To develop/build: ``` git submodule update --init +cargo build ``` -Docs: (TODO link) +Docs: waiting on other crates to be published. diff --git a/kinode-wit b/kinode-wit index aa2c8b1..758fac1 160000 --- a/kinode-wit +++ b/kinode-wit @@ -1 +1 @@ -Subproject commit aa2c8b11c9171b949d1991c32f58591c0e881f85 +Subproject commit 758fac1fb144f89c2a486778c62cbea2fb5840ac diff --git a/src/eth.rs b/src/eth.rs index aff0083..72d0a6f 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -1,4 +1,5 @@ use crate::{Message, Request as KiRequest}; +use alloy_json_rpc::ErrorPayload; pub use alloy_primitives::{Address, BlockHash, BlockNumber, Bytes, TxHash, U128, U256, U64, U8}; pub use alloy_rpc_types::pubsub::{Params, SubscriptionKind, SubscriptionResult}; pub use alloy_rpc_types::{ @@ -70,8 +71,10 @@ pub enum EthResponse { Err(EthError), } -#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Serialize, Deserialize)] pub enum EthError { + /// RPC provider returned an error + RpcError(ErrorPayload), /// provider module cannot parse message MalformedRequest, /// No RPC provider for the chain @@ -92,9 +95,6 @@ pub enum EthError { /// The action type used for configuring eth:distro:sys. Only processes which have the "root" /// capability from eth:distro:sys can successfully send this action. -/// -/// NOTE: changes to config will not be persisted between boots, they must be saved in .env -/// to be reflected between boots. TODO: can change this #[derive(Debug, Serialize, Deserialize)] pub enum EthConfigAction { /// Add a new provider to the list of providers. @@ -165,8 +165,8 @@ pub struct ProviderConfig { #[derive(Clone, Debug, Deserialize, Serialize, Hash, Eq, PartialEq)] pub enum NodeOrRpcUrl { Node { - kns_update: crate::kernel_types::KnsUpdate, - use_as_provider: bool, // for routers inside saved config + kns_update: crate::net::KnsUpdate, + use_as_provider: bool, // false for just-routers inside saved config }, RpcUrl(String), } diff --git a/src/http.rs b/src/http.rs index 85cf1d2..c5298b6 100644 --- a/src/http.rs +++ b/src/http.rs @@ -494,6 +494,224 @@ where resp } +/// Register a new path with the HTTP server. This will cause the HTTP server to +/// forward any requests on this path to the calling process. +/// +/// Instead of binding at just a path, this function tells the HTTP server to +/// generate a *subdomain* with our package ID (with non-ascii-alphanumeric +/// characters converted to `-`) and bind at that subdomain. +pub fn secure_bind_http_path(path: T) -> std::result::Result<(), HttpServerError> +where + T: Into, +{ + let res = KiRequest::to(("our", "http_server", "distro", "sys")) + .body( + serde_json::to_vec(&HttpServerAction::SecureBind { + path: path.into(), + cache: false, + }) + .unwrap(), + ) + .send_and_await_response(5) + .unwrap(); + let Ok(Message::Response { body, .. }) = res else { + return Err(HttpServerError::PathBindError { + error: "http_server timed out".to_string(), + }); + }; + let Ok(resp) = serde_json::from_slice::>(&body) else { + return Err(HttpServerError::PathBindError { + error: "http_server gave unexpected response".to_string(), + }); + }; + resp +} + +/// Register a new path with the HTTP server, and serve a static file from it. +/// The server will respond to GET requests on this path with the given file. +/// +/// Instead of binding at just a path, this function tells the HTTP server to +/// generate a *subdomain* with our package ID (with non-ascii-alphanumeric +/// characters converted to `-`) and bind at that subdomain. +pub fn secure_bind_http_static_path( + path: T, + content_type: Option, + content: Vec, +) -> std::result::Result<(), HttpServerError> +where + T: Into, +{ + let res = KiRequest::to(("our", "http_server", "distro", "sys")) + .body( + serde_json::to_vec(&HttpServerAction::SecureBind { + path: path.into(), + cache: true, + }) + .unwrap(), + ) + .blob(KiBlob { + mime: content_type, + bytes: content, + }) + .send_and_await_response(5) + .unwrap(); + let Ok(Message::Response { body, .. }) = res else { + return Err(HttpServerError::PathBindError { + error: "http_server timed out".to_string(), + }); + }; + let Ok(resp) = serde_json::from_slice::>(&body) else { + return Err(HttpServerError::PathBindError { + error: "http_server gave unexpected response".to_string(), + }); + }; + resp +} + +/// Register a WebSockets path with the HTTP server. Your app must do this +/// in order to receive incoming WebSocket connections. +/// +/// Instead of binding at just a path, this function tells the HTTP server to +/// generate a *subdomain* with our package ID (with non-ascii-alphanumeric +/// characters converted to `-`) and bind at that subdomain. +pub fn secure_bind_ws_path(path: T, encrypted: bool) -> std::result::Result<(), HttpServerError> +where + T: Into, +{ + let res = KiRequest::to(("our", "http_server", "distro", "sys")) + .body( + serde_json::to_vec(&HttpServerAction::WebSocketSecureBind { + path: path.into(), + encrypted, + extension: false, + }) + .unwrap(), + ) + .send_and_await_response(5) + .unwrap(); + let Ok(Message::Response { body, .. }) = res else { + return Err(HttpServerError::PathBindError { + error: "http_server timed out".to_string(), + }); + }; + let Ok(resp) = serde_json::from_slice::>(&body) else { + return Err(HttpServerError::PathBindError { + error: "http_server gave unexpected response".to_string(), + }); + }; + resp +} + +/// Serve index.html +/// +/// Instead of binding at just a path, this function tells the HTTP server to +/// generate a *subdomain* with our package ID (with non-ascii-alphanumeric +/// characters converted to `-`) and bind at that subdomain. +pub fn secure_serve_index_html( + our: &Address, + directory: &str, + paths: Vec<&str>, +) -> anyhow::Result<()> { + KiRequest::to(("our", "vfs", "distro", "sys")) + .body(serde_json::to_vec(&VfsRequest { + path: format!("/{}/pkg/{}/index.html", our.package_id(), directory), + action: VfsAction::Read, + })?) + .send_and_await_response(5)??; + + let Some(blob) = get_blob() else { + return Err(anyhow::anyhow!("serve_index_html: no index.html blob")); + }; + + let index = String::from_utf8(blob.bytes)?; + + for path in paths { + secure_bind_http_static_path( + path, + Some("text/html".to_string()), + index.to_string().as_bytes().to_vec(), + )?; + } + + Ok(()) +} + +/// Serve static files from a given directory by binding all of them +/// in http_server to their filesystem path. +/// +/// Instead of binding at just a path, this function tells the HTTP server to +/// generate a *subdomain* with our package ID (with non-ascii-alphanumeric +/// characters converted to `-`) and bind at that subdomain. +pub fn secure_serve_ui(our: &Address, directory: &str, paths: Vec<&str>) -> anyhow::Result<()> { + secure_serve_index_html(our, directory, paths)?; + + let initial_path = format!("{}/pkg/{}", our.package_id(), directory); + + let mut queue = VecDeque::new(); + queue.push_back(initial_path.clone()); + + while let Some(path) = queue.pop_front() { + let Ok(directory_response) = KiRequest::to(("our", "vfs", "distro", "sys")) + .body(serde_json::to_vec(&VfsRequest { + path, + action: VfsAction::ReadDir, + })?) + .send_and_await_response(5)? + else { + return Err(anyhow::anyhow!("serve_ui: no response for path")); + }; + + let directory_body = serde_json::from_slice::(directory_response.body())?; + + // Determine if it's a file or a directory and handle appropriately + match directory_body { + VfsResponse::ReadDir(directory_info) => { + for entry in directory_info { + match entry.file_type { + // If it's a file, serve it statically + FileType::File => { + KiRequest::to(("our", "vfs", "distro", "sys")) + .body(serde_json::to_vec(&VfsRequest { + path: entry.path.clone(), + action: VfsAction::Read, + })?) + .send_and_await_response(5)??; + + let Some(blob) = get_blob() else { + return Err(anyhow::anyhow!( + "serve_ui: no blob for {}", + entry.path + )); + }; + + let content_type = get_mime_type(&entry.path); + + secure_bind_http_static_path( + entry.path.replace(&initial_path, ""), + Some(content_type), + blob.bytes, + )?; + } + FileType::Directory => { + // Push the directory onto the queue + queue.push_back(entry.path); + } + _ => {} + } + } + } + _ => { + return Err(anyhow::anyhow!( + "serve_ui: unexpected response for path: {:?}", + directory_body + )) + } + }; + } + + Ok(()) +} + /// Register a WebSockets path with the HTTP server to send and /// receive system messages from a runtime extension. Only use /// this if you are writing a runtime extension. diff --git a/src/kernel_types.rs b/src/kernel_types.rs index d3d7398..f2cd487 100644 --- a/src/kernel_types.rs +++ b/src/kernel_types.rs @@ -47,6 +47,18 @@ pub struct Capability { pub params: String, // JSON-string } +impl std::fmt::Display for Capability { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}({})", + self.issuer, + serde_json::from_str::(&self.params) + .unwrap_or(serde_json::json!("invalid JSON in capability")) + ) + } +} + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct SendError { pub kind: SendErrorKind, @@ -139,16 +151,27 @@ pub enum KernelResponse { StartedProcess, RunProcessError, KilledProcess(ProcessId), + Debug(KernelPrintResponse), +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum KernelPrintResponse { + ProcessMap(ProcessMap), + Process(Option), + HasCap(Option), } +pub type ProcessMap = HashMap; + +// NOTE: this is different from the runtime representation of a process +// in that the capabilities are stored as a HashSet instead of a HashMap. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct PersistedProcess { pub wasm_bytes_handle: String, - // pub drive: String, - // pub full_path: String, + pub wit_version: Option, pub on_exit: OnExit, pub capabilities: HashSet, - pub public: bool, // marks if a process allows messages from any process + pub public: bool, } #[derive(Serialize, Deserialize, Debug)] @@ -229,6 +252,7 @@ pub struct Erc721Metadata { /// - `license`: An optional field containing the license of the package. /// - `screenshots`: An optional field containing a list of URLs to screenshots of the package. /// - `wit_version`: An optional field containing the version of the WIT standard that the package adheres to. +/// - `dependencies`: An optional field containing a list of `PackageId`s: API dependencies. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Erc721Properties { pub package_name: String, @@ -238,7 +262,8 @@ pub struct Erc721Properties { pub code_hashes: HashMap, pub license: Option, pub screenshots: Option>, - pub wit_version: Option<(u32, u32, u32)>, + pub wit_version: Option, + pub dependencies: Option>, } /// the type that gets deserialized from each entry in the array in `manifest.json` @@ -261,6 +286,7 @@ pub struct DotScriptsEntry { pub request_networking: bool, pub request_capabilities: Option>, pub grant_capabilities: Option>, + pub wit_version: Option, } impl std::fmt::Display for Message { @@ -415,6 +441,7 @@ pub fn en_wit_message(message: Message) -> wit::Message { pub fn en_wit_send_error(error: SendError) -> wit::SendError { wit::SendError { kind: en_wit_send_error_kind(error.kind), + target: en_wit_address(error.target), message: en_wit_message(error.message), lazy_load_blob: en_wit_blob(error.lazy_load_blob), } @@ -432,14 +459,3 @@ pub enum MessageType { Request, Response, } - -#[derive(Clone, Debug, Serialize, Deserialize, Hash, Eq, PartialEq)] -pub struct KnsUpdate { - pub name: String, // actual username / domain name - pub owner: String, - pub node: String, // hex namehash of node - pub public_key: String, - pub ip: String, - pub port: u16, - pub routers: Vec, -} diff --git a/src/lib.rs b/src/lib.rs index 2c9f7aa..0796b54 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,7 @@ use serde_json::Value; wit_bindgen::generate!({ path: "kinode-wit", + generate_unused_types: true, world: "lib", }); @@ -53,13 +54,13 @@ pub use types::{ address::{Address, AddressParseError}, capability::Capability, lazy_load_blob::LazyLoadBlob, - message::wit_message_to_message, - message::{Message, SendError, SendErrorKind}, + message::{Message, _wit_message_to_message}, on_exit::OnExit, package_id::PackageId, process_id::{ProcessId, ProcessIdParseError}, request::Request, response::Response, + send_error::{SendError, SendErrorKind, _wit_send_error_to_send_error}, }; /// Implement the wit-bindgen specific code that the kernel uses to hook into @@ -98,22 +99,26 @@ macro_rules! println { /// attempts to send a message to another node, that message may bounce back with /// a `SendError`. Those should be handled here. /// -/// TODO: example of usage +/// Example: +/// ```no_run +/// use kinode_process_lib::await_message; +/// +/// loop { +/// match await_message() { +/// Ok(msg) => { +/// println!("Received message: {:?}", msg); +/// // Do something with the message +/// } +/// Err(send_error) => { +/// println!("Error sending message: {:?}", send_error); +/// } +/// } +/// } +/// ``` pub fn await_message() -> Result { match crate::receive() { - Ok((source, message)) => Ok(wit_message_to_message(source, message)), - Err((send_err, context)) => Err(SendError { - kind: match send_err.kind { - crate::kinode::process::standard::SendErrorKind::Offline => SendErrorKind::Offline, - crate::kinode::process::standard::SendErrorKind::Timeout => SendErrorKind::Timeout, - }, - message: wit_message_to_message( - Address::new("our", ProcessId::new(Some("net"), "distro", "sys")), - send_err.message, - ), - lazy_load_blob: send_err.lazy_load_blob, - context, - }), + Ok((source, message)) => Ok(_wit_message_to_message(source, message)), + Err((send_err, context)) => Err(_wit_send_error_to_send_error(send_err, context)), } } @@ -139,7 +144,25 @@ pub fn spawn( /// Create a blob with no MIME type and a generic type, plus a serializer /// function that turns that type into bytes. /// -/// Example: TODO +/// Example usage: +/// ```no_run +/// use kinode_process_lib::make_blob; +/// use bincode; +/// use serde::{Serialize, Deserialize}; +/// +/// #[derive(Serialize, Deserialize)] +/// struct MyType { +/// field: std::collections::HashMap, +/// field_two: std::collections::HashSet, +/// } +/// +/// let my_type = MyType { +/// field: std::collections::HashMap::new(), +/// field_two: std::collections::HashSet::new(), +/// }; +/// +/// make_blob(&my_type, |t| Ok(bincode::serialize(t)?)); +/// ``` pub fn make_blob(blob: &T, serializer: F) -> anyhow::Result where F: Fn(&T) -> anyhow::Result>, @@ -155,7 +178,18 @@ where /// it from bytes with the provided function. /// /// Example: -/// ``` +/// ```no_run +/// use std::collections::{HashMap, HashSet}; +/// use kinode_process_lib::get_typed_blob; +/// use bincode; +/// use serde::{Serialize, Deserialize}; +/// +/// #[derive(Serialize, Deserialize)] +/// struct MyType { +/// field: HashMap, +/// field_two: HashSet, +/// } +/// /// get_typed_blob(|bytes| Ok(bincode::deserialize(bytes)?)).unwrap_or(MyType { /// field: HashMap::new(), /// field_two: HashSet::new(), @@ -179,7 +213,18 @@ where /// If it does, attempt to deserialize it from bytes with the provided function. /// /// Example: -/// ``` +/// ```no_run +/// use std::collections::{HashMap, HashSet}; +/// use kinode_process_lib::get_typed_state; +/// use bincode; +/// use serde::{Serialize, Deserialize}; +/// +/// #[derive(Serialize, Deserialize)] +/// struct MyStateType { +/// field: HashMap, +/// field_two: HashSet, +/// } +/// /// get_typed_state(|bytes| Ok(bincode::deserialize(bytes)?)).unwrap_or(MyStateType { /// field: HashMap::new(), /// field_two: HashSet::new(), diff --git a/src/net.rs b/src/net.rs index e03fa12..9ed287b 100644 --- a/src/net.rs +++ b/src/net.rs @@ -1,4 +1,6 @@ -use crate::*; +use crate::{get_blob, Address, NodeId, Request, SendError}; +use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; // // Networking protocol types @@ -8,8 +10,34 @@ use crate::*; pub struct Identity { pub name: NodeId, pub networking_key: String, - pub ws_routing: Option<(String, u16)>, - pub allowed_routers: Vec, + pub routing: NodeRouting, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum NodeRouting { + Routers(Vec), + Direct { + ip: String, + ports: BTreeMap, + }, +} + +impl Identity { + pub fn is_direct(&self) -> bool { + matches!(&self.routing, NodeRouting::Direct { .. }) + } + pub fn get_protocol_port(&self, protocol: &str) -> Option { + match &self.routing { + NodeRouting::Routers(_) => None, + NodeRouting::Direct { ports, .. } => ports.get(protocol).cloned(), + } + } + pub fn routers(&self) -> Option<&Vec> { + match &self.routing { + NodeRouting::Routers(routers) => Some(routers), + NodeRouting::Direct { .. } => None, + } + } } /// Must be parsed from message pack vector. @@ -69,17 +97,23 @@ pub enum NetResponse { Verified(bool), } -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize, Hash, Eq, PartialEq)] pub struct KnsUpdate { pub name: String, // actual username / domain name pub owner: String, pub node: String, // hex namehash of node pub public_key: String, - pub ip: String, - pub port: u16, + pub ips: Vec, + pub ports: BTreeMap, pub routers: Vec, } +impl KnsUpdate { + pub fn get_protocol_port(&self, protocol: &str) -> u16 { + self.ports.get(protocol).cloned().unwrap_or(0) + } +} + // // Helpers // diff --git a/src/types/address.rs b/src/types/address.rs index 01558e9..7d5d7e3 100644 --- a/src/types/address.rs +++ b/src/types/address.rs @@ -1,8 +1,8 @@ -pub use crate::{Address, PackageId, ProcessId}; +pub use crate::{Address, ProcessId}; use serde::{Deserialize, Serialize}; use std::hash::{Hash, Hasher}; -/// Address is defined in the wit bindings, but constructors and methods here. +/// Address is defined in `kinode.wit`, but constructors and methods here. /// An `Address` is a combination of a node ID (string) and a [`ProcessId`]. It is /// used in the Request/Response pattern to indicate which process on a given node /// in the network to direct the message to. The formatting structure for @@ -39,8 +39,8 @@ impl Address { &self.process.publisher_node } /// Read the package_id (package + publisher) from an `Address`. - pub fn package_id(&self) -> PackageId { - PackageId::new(self.package(), self.publisher()) + pub fn package_id(&self) -> crate::PackageId { + crate::PackageId::new(self.package(), self.publisher()) } } @@ -49,36 +49,42 @@ impl std::str::FromStr for Address { /// Attempt to parse an `Address` from a string. The formatting structure for /// an Address is `node@process_name:package_name:publisher_node`. /// - /// TODO: clarify if `@` can be present in process name / package name / publisher name - /// - /// TODO: ensure `:` cannot sneak into first segment + /// The string being parsed must contain exactly one `@` and three `:` characters. + /// The `@` character separates the node ID from the rest of the address, and the + /// `:` characters separate the process name, package name, and publisher node ID. fn from_str(input: &str) -> Result { - // split string on colons into 4 segments, - // first one with @, next 3 with : - let mut name_rest = input.split('@'); - let node = name_rest - .next() - .ok_or(AddressParseError::MissingField)? - .to_string(); - let mut segments = name_rest - .next() - .ok_or(AddressParseError::MissingNodeId)? - .split(':'); - let process_name = segments - .next() - .ok_or(AddressParseError::MissingField)? - .to_string(); - let package_name = segments - .next() - .ok_or(AddressParseError::MissingField)? - .to_string(); - let publisher_node = segments - .next() - .ok_or(AddressParseError::MissingField)? - .to_string(); - if segments.next().is_some() { + // split string on '@' and ensure there is exactly one '@' + let parts: Vec<&str> = input.split('@').collect(); + if parts.len() < 2 { + return Err(AddressParseError::MissingNodeId); + } else if parts.len() > 2 { + return Err(AddressParseError::TooManyAts); + } + let node = parts[0].to_string(); + if node.is_empty() { + return Err(AddressParseError::MissingNodeId); + } + + // split the rest on ':' and ensure there are exactly three ':' + let segments: Vec<&str> = parts[1].split(':').collect(); + if segments.len() < 3 { + return Err(AddressParseError::MissingField); + } else if segments.len() > 3 { return Err(AddressParseError::TooManyColons); } + let process_name = segments[0].to_string(); + if process_name.is_empty() { + return Err(AddressParseError::MissingField); + } + let package_name = segments[1].to_string(); + if package_name.is_empty() { + return Err(AddressParseError::MissingField); + } + let publisher_node = segments[2].to_string(); + if publisher_node.is_empty() { + return Err(AddressParseError::MissingField); + } + Ok(Address { node, process: ProcessId { @@ -163,6 +169,7 @@ impl std::fmt::Display for Address { /// Error type for parsing an `Address` from a string. #[derive(Debug)] pub enum AddressParseError { + TooManyAts, TooManyColons, MissingNodeId, MissingField, @@ -170,24 +177,85 @@ pub enum AddressParseError { impl std::fmt::Display for AddressParseError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{}", - match self { - AddressParseError::TooManyColons => "Too many colons in ProcessId string", - AddressParseError::MissingNodeId => "Node ID missing", - AddressParseError::MissingField => "Missing field in ProcessId string", - } - ) + write!(f, "{self}") } } impl std::error::Error for AddressParseError { fn description(&self) -> &str { match self { + AddressParseError::TooManyAts => "Too many '@' chars in ProcessId string", AddressParseError::TooManyColons => "Too many colons in ProcessId string", AddressParseError::MissingNodeId => "Node ID missing", AddressParseError::MissingField => "Missing field in ProcessId string", } } } + +#[cfg(test)] +mod tests { + use super::*; + use std::str::FromStr; + + #[test] + fn test_valid_address() { + let input = "node123@process1:packageA:publisherB"; + let address: Address = input.parse().unwrap(); + assert_eq!(address.node(), "node123"); + assert_eq!(address.process(), "process1"); + assert_eq!(address.package(), "packageA"); + assert_eq!(address.publisher(), "publisherB"); + } + + #[test] + fn test_missing_node_id() { + let input = "@process1:packageA:publisherB"; + assert!(matches!( + Address::from_str(input), + Err(AddressParseError::MissingNodeId) + )); + } + + #[test] + fn test_too_many_ats() { + let input = "node123@process1@packageA:publisherB"; + assert!(matches!( + Address::from_str(input), + Err(AddressParseError::TooManyAts) + )); + } + + #[test] + fn test_missing_field() { + let input = "node123@process1:packageA"; + assert!(matches!( + Address::from_str(input), + Err(AddressParseError::MissingField) + )); + } + + #[test] + fn test_too_many_colons() { + let input = "node123@process1:packageA:publisherB:extra"; + assert!(matches!( + Address::from_str(input), + Err(AddressParseError::TooManyColons) + )); + } + + #[test] + fn test_empty_input() { + let input = ""; + assert!(matches!( + Address::from_str(input), + Err(AddressParseError::MissingNodeId) + )); + } + + #[test] + fn test_display() { + let input = "node123@process1:packageA:publisherB"; + let address: Address = input.parse().unwrap(); + assert_eq!(format!("{}", address), input); + } +} diff --git a/src/types/capability.rs b/src/types/capability.rs index d43e4e1..ce5c26e 100644 --- a/src/types/capability.rs +++ b/src/types/capability.rs @@ -5,7 +5,7 @@ use std::hash::{Hash, Hasher}; /// Capability is defined in the wit bindings, but constructors and methods here. /// A `Capability` is a combination of an Address and a set of Params (a serialized -/// json string). Capabilities are attached to messages to either share that capability +/// JSON string). Capabilities are attached to messages to either share that capability /// with the receiving process, or to prove that a process has authority to perform a /// certain action. impl Capability { @@ -28,6 +28,15 @@ impl Capability { pub fn params(&self) -> &str { &self.params } + /// Read the params from a `Capability` as a `serde_json::Value`. + pub fn params_json(&self) -> Result { + serde_json::from_str(&self.params) + } + /// Set the params for a `Capability` from a `serde_json::Value`. + pub fn set_params_json(&mut self, value: serde_json::Value) -> Result<(), serde_json::Error> { + self.params = serde_json::to_string(&value)?; + Ok(()) + } } impl Serialize for Capability { diff --git a/src/types/lazy_load_blob.rs b/src/types/lazy_load_blob.rs index 8e4e65b..f50c929 100644 --- a/src/types/lazy_load_blob.rs +++ b/src/types/lazy_load_blob.rs @@ -1,5 +1,27 @@ pub use crate::LazyLoadBlob; +impl LazyLoadBlob { + /// Create a new `LazyLoadBlob`. Takes a mime type and a byte vector. + pub fn new(mime: Option, bytes: U) -> LazyLoadBlob + where + T: Into, + U: Into>, + { + LazyLoadBlob { + mime: mime.map(|mime| mime.into()), + bytes: bytes.into(), + } + } + /// Read the mime type from a `LazyLoadBlob`. + pub fn mime(&self) -> Option<&str> { + self.mime.as_ref().map(|mime| mime.as_str()) + } + /// Read the bytes from a `LazyLoadBlob`. + pub fn bytes(&self) -> &[u8] { + &self.bytes + } +} + impl std::default::Default for LazyLoadBlob { fn default() -> Self { LazyLoadBlob { diff --git a/src/types/message.rs b/src/types/message.rs index 0f36a10..d167c97 100644 --- a/src/types/message.rs +++ b/src/types/message.rs @@ -1,4 +1,5 @@ -use crate::*; +use crate::{Address, Capability, LazyLoadBlob, ProcessId}; +use serde::{Deserialize, Serialize}; /// The basic message type. A message is either a request or a response. Best /// practice when handling a message is to do this: @@ -46,14 +47,16 @@ impl Message { Message::Response { metadata, .. } => metadata.as_ref().map(|s| s.as_str()), } } - /// Get the context of a message. + /// Get the context of a message. Always `None` for requests. pub fn context(&self) -> Option<&[u8]> { match self { Message::Request { .. } => None, Message::Response { context, .. } => context.as_ref().map(|s| s.as_slice()), } } - /// Get the blob of a message, if any. + /// Get the blob of a message, if any. This function must be called + /// by the process that received the message **before** receiving another + /// message! The blob can only be consumed immediately after receiving a message. pub fn blob(&self) -> Option { crate::get_blob() } @@ -66,10 +69,7 @@ impl Message { } /// Check if a message is a request. Returns `false` if it's a response. pub fn is_request(&self) -> bool { - match self { - Message::Request { .. } => true, - Message::Response { .. } => false, - } + matches!(self, Message::Request { .. }) } /// Check if a message was sent by a local process. Returns `false` if the /// source node is not our local node. @@ -79,6 +79,8 @@ impl Message { Message::Response { source, .. } => source.node == our.node, } } + /// Check the `ProcessId` of a message source against a given `ProcessId` or + /// something that can be checked for equality against a `ProcessId`. pub fn is_process(&self, process: T) -> bool where ProcessId: PartialEq, @@ -90,63 +92,7 @@ impl Message { } } -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum SendErrorKind { - Offline, - Timeout, -} - -impl SendErrorKind { - pub fn is_offline(&self) -> bool { - matches!(self, SendErrorKind::Offline) - } - pub fn is_timeout(&self) -> bool { - matches!(self, SendErrorKind::Timeout) - } -} - -#[derive(Debug, Clone)] -pub struct SendError { - pub kind: SendErrorKind, - pub message: Message, - pub lazy_load_blob: Option, - pub context: Option>, -} - -impl SendError { - pub fn kind(&self) -> &SendErrorKind { - &self.kind - } - pub fn message(&self) -> &Message { - &self.message - } - pub fn blob(&self) -> Option<&LazyLoadBlob> { - self.lazy_load_blob.as_ref() - } - pub fn context(&self) -> Option<&[u8]> { - self.context.as_deref() - } -} - -impl std::fmt::Display for SendError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match &self.kind { - SendErrorKind::Offline => write!(f, "Offline"), - SendErrorKind::Timeout => write!(f, "Timeout"), - } - } -} - -impl std::error::Error for SendError { - fn description(&self) -> &str { - match &self.kind { - SendErrorKind::Offline => "Offline", - SendErrorKind::Timeout => "Timeout", - } - } -} - -pub fn wit_message_to_message( +pub fn _wit_message_to_message( source: Address, message: crate::kinode::process::standard::Message, ) -> Message { diff --git a/src/types/mod.rs b/src/types/mod.rs index ad223f5..e5b350c 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -7,3 +7,4 @@ pub mod package_id; pub mod process_id; pub mod request; pub mod response; +pub mod send_error; diff --git a/src/types/on_exit.rs b/src/types/on_exit.rs index 61f6a86..2cec248 100644 --- a/src/types/on_exit.rs +++ b/src/types/on_exit.rs @@ -1,4 +1,4 @@ -use crate::*; +use crate::{Address, LazyLoadBlob, Request}; #[derive(Clone, Debug)] pub enum OnExit { @@ -24,7 +24,7 @@ impl OnExit { metadata: req.1.metadata, blob: req.2, context: None, - capabilities: req.1.capabilities, // TODO double check + capabilities: req.1.capabilities, }); } OnExit::Requests(requests) @@ -87,21 +87,21 @@ impl OnExit { OnExit::Requests(reqs) => { let mut kernel_reqs: Vec<( Address, - kinode::process::standard::Request, + crate::kinode::process::standard::Request, Option, )> = Vec::with_capacity(reqs.len()); for req in reqs { kernel_reqs.push(( req.target .ok_or(anyhow::anyhow!("request without target given"))?, - kinode::process::standard::Request { + crate::kinode::process::standard::Request { inherit: req.inherit, expects_response: None, body: req .body .ok_or(anyhow::anyhow!("request without body given"))?, metadata: req.metadata, - capabilities: req.capabilities, // TODO double check + capabilities: req.capabilities, }, req.blob, )); diff --git a/src/types/package_id.rs b/src/types/package_id.rs index f82a08d..61d43e7 100644 --- a/src/types/package_id.rs +++ b/src/types/package_id.rs @@ -1,15 +1,9 @@ +pub use crate::PackageId; use crate::ProcessIdParseError; use serde::{Deserialize, Serialize}; -use std::hash::Hash; - -/// PackageId is like a ProcessId, but for a package. Only contains the name -/// of the package and the name of the publisher. -#[derive(Hash, Eq, PartialEq, Debug, Clone, Serialize, Deserialize)] -pub struct PackageId { - package_name: String, - publisher_node: String, -} +/// `PackageId` is defined in the wit bindings, but constructors and methods +/// are defined here. A `PackageId` contains a package name and a publisher node ID. impl PackageId { /// Create a new `PackageId`. pub fn new(package_name: &str, publisher_node: &str) -> Self { @@ -31,29 +25,51 @@ impl PackageId { } } +impl Serialize for PackageId { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + format!("{}", self).serialize(serializer) + } +} + +impl<'a> Deserialize<'a> for PackageId { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + let s = String::deserialize(deserializer)?; + s.parse().map_err(serde::de::Error::custom) + } +} + impl std::str::FromStr for PackageId { type Err = ProcessIdParseError; /// Attempt to parse a `PackageId` from a string. The string must - /// contain exactly two segments, where segments are strings separated - /// by a colon `:`. The segments cannot themselves contain colons. + /// contain exactly two segments, where segments are non-empty strings + /// separated by a colon (`:`). The segments cannot themselves contain colons. + /// /// Please note that while any string without colons will parse successfully /// to create a `PackageId`, not all strings without colons are actually /// valid usernames, which the `publisher_node` field of a `PackageId` will /// always in practice be. fn from_str(input: &str) -> Result { - // split string on colons into 2 segments - let mut segments = input.split(':'); - let package_name = segments - .next() - .ok_or(ProcessIdParseError::MissingField)? - .to_string(); - let publisher_node = segments - .next() - .ok_or(ProcessIdParseError::MissingField)? - .to_string(); - if segments.next().is_some() { + let segments: Vec<&str> = input.split(':').collect(); + if segments.len() < 2 { + return Err(ProcessIdParseError::MissingField); + } else if segments.len() > 2 { return Err(ProcessIdParseError::TooManyColons); } + let package_name = segments[0].to_string(); + if package_name.is_empty() { + return Err(ProcessIdParseError::MissingField); + } + let publisher_node = segments[1].to_string(); + if publisher_node.is_empty() { + return Err(ProcessIdParseError::MissingField); + } + Ok(PackageId { package_name, publisher_node, @@ -61,8 +77,29 @@ impl std::str::FromStr for PackageId { } } +impl std::hash::Hash for PackageId { + fn hash(&self, state: &mut H) { + self.package_name.hash(state); + self.publisher_node.hash(state); + } +} + impl std::fmt::Display for PackageId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}:{}", self.package_name, self.publisher_node) } } + +impl From<(&str, &str)> for PackageId { + fn from(input: (&str, &str)) -> Self { + PackageId::new(input.0, input.1) + } +} + +impl std::cmp::Eq for PackageId {} + +impl PartialEq for PackageId { + fn eq(&self, other: &Self) -> bool { + self.package_name == other.package_name && self.publisher_node == other.publisher_node + } +} diff --git a/src/types/process_id.rs b/src/types/process_id.rs index 8138429..608c867 100644 --- a/src/types/process_id.rs +++ b/src/types/process_id.rs @@ -43,23 +43,24 @@ impl std::str::FromStr for ProcessId { /// valid usernames, which the `publisher_node` field of a `ProcessId` will /// always in practice be. fn from_str(input: &str) -> Result { - // split string on colons into 3 segments - let mut segments = input.split(':'); - let process_name = segments - .next() - .ok_or(ProcessIdParseError::MissingField)? - .to_string(); - let package_name = segments - .next() - .ok_or(ProcessIdParseError::MissingField)? - .to_string(); - let publisher_node = segments - .next() - .ok_or(ProcessIdParseError::MissingField)? - .to_string(); - if segments.next().is_some() { + let segments: Vec<&str> = input.split(':').collect(); + if segments.len() < 3 { + return Err(ProcessIdParseError::MissingField); + } else if segments.len() > 3 { return Err(ProcessIdParseError::TooManyColons); } + let process_name = segments[0].to_string(); + if process_name.is_empty() { + return Err(ProcessIdParseError::MissingField); + } + let package_name = segments[1].to_string(); + if package_name.is_empty() { + return Err(ProcessIdParseError::MissingField); + } + let publisher_node = segments[2].to_string(); + if publisher_node.is_empty() { + return Err(ProcessIdParseError::MissingField); + } Ok(ProcessId { process_name, package_name, @@ -145,8 +146,8 @@ impl std::fmt::Display for ProcessIdParseError { f, "{}", match self { - ProcessIdParseError::TooManyColons => "Too many colons in ProcessId string", - ProcessIdParseError::MissingField => "Missing field in ProcessId string", + ProcessIdParseError::TooManyColons => "Too many colons", + ProcessIdParseError::MissingField => "Missing field", } ) } @@ -155,8 +156,8 @@ impl std::fmt::Display for ProcessIdParseError { impl std::error::Error for ProcessIdParseError { fn description(&self) -> &str { match self { - ProcessIdParseError::TooManyColons => "Too many colons in ProcessId string", - ProcessIdParseError::MissingField => "Missing field in ProcessId string", + ProcessIdParseError::TooManyColons => "Too many colons", + ProcessIdParseError::MissingField => "Missing field", } } } diff --git a/src/types/request.rs b/src/types/request.rs index 440d086..f5fb687 100644 --- a/src/types/request.rs +++ b/src/types/request.rs @@ -1,4 +1,7 @@ -use crate::*; +use crate::{ + Address, Capability, LazyLoadBlob, Message, SendError, _wit_message_to_message, + _wit_send_error_to_send_error, +}; /// Request builder. Use [`Request::new()`] to start a request, then build it, /// then call [`Request::send()`] on it to fire. @@ -274,23 +277,8 @@ impl Request { }, self.blob.as_ref(), ) { - Ok((source, message)) => Ok(Ok(wit_message_to_message(source, message))), - Err(send_err) => Ok(Err(SendError { - kind: match send_err.kind { - crate::kinode::process::standard::SendErrorKind::Offline => { - SendErrorKind::Offline - } - crate::kinode::process::standard::SendErrorKind::Timeout => { - SendErrorKind::Timeout - } - }, - message: wit_message_to_message( - Address::new("our", ProcessId::new(Some("net"), "distro", "sys")), - send_err.message, - ), - lazy_load_blob: send_err.lazy_load_blob, - context: None, - })), + Ok((source, message)) => Ok(Ok(_wit_message_to_message(source, message))), + Err(send_err) => Ok(Err(_wit_send_error_to_send_error(send_err, self.context))), } } else { Err(anyhow::anyhow!("missing fields")) diff --git a/src/types/response.rs b/src/types/response.rs index 1db4d9a..b0ee16c 100644 --- a/src/types/response.rs +++ b/src/types/response.rs @@ -10,7 +10,6 @@ pub struct Response { capabilities: Vec, } -#[allow(dead_code)] impl Response { /// Start building a new response. Attempting to send this response will /// not succeed until its `body` has been set with `body()` or `try_body()`. diff --git a/src/types/send_error.rs b/src/types/send_error.rs new file mode 100644 index 0000000..fe9d2d7 --- /dev/null +++ b/src/types/send_error.rs @@ -0,0 +1,78 @@ +use crate::{Address, LazyLoadBlob, Message, _wit_message_to_message}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone)] +pub struct SendError { + pub kind: SendErrorKind, + pub target: Address, + pub message: Message, + pub lazy_load_blob: Option, + pub context: Option>, +} + +impl SendError { + pub fn kind(&self) -> &SendErrorKind { + &self.kind + } + pub fn target(&self) -> &Address { + &self.target + } + pub fn message(&self) -> &Message { + &self.message + } + pub fn blob(&self) -> Option<&LazyLoadBlob> { + self.lazy_load_blob.as_ref() + } + pub fn context(&self) -> Option<&[u8]> { + self.context.as_deref() + } +} + +impl std::fmt::Display for SendError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match &self.kind { + SendErrorKind::Offline => write!(f, "Offline"), + SendErrorKind::Timeout => write!(f, "Timeout"), + } + } +} + +impl std::error::Error for SendError { + fn description(&self) -> &str { + match &self.kind { + SendErrorKind::Offline => "Offline", + SendErrorKind::Timeout => "Timeout", + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum SendErrorKind { + Offline, + Timeout, +} + +impl SendErrorKind { + pub fn is_offline(&self) -> bool { + matches!(self, SendErrorKind::Offline) + } + pub fn is_timeout(&self) -> bool { + matches!(self, SendErrorKind::Timeout) + } +} + +pub fn _wit_send_error_to_send_error( + send_err: crate::kinode::process::standard::SendError, + context: Option>, +) -> SendError { + SendError { + kind: match send_err.kind { + crate::kinode::process::standard::SendErrorKind::Offline => SendErrorKind::Offline, + crate::kinode::process::standard::SendErrorKind::Timeout => SendErrorKind::Timeout, + }, + target: send_err.target.clone(), + message: _wit_message_to_message(send_err.target, send_err.message), + lazy_load_blob: send_err.lazy_load_blob, + context, + } +}