diff --git a/examples/feeds/01_feed_client/package.json b/examples/feeds/01_feed_client/package.json index f3b1294ae..777218bda 100644 --- a/examples/feeds/01_feed_client/package.json +++ b/examples/feeds/01_feed_client/package.json @@ -18,9 +18,9 @@ "@project-serum/borsh": "^0.2.5", "@solana/spl-token": "^0.3.8", "@solana/web3.js": "^1.78.3", - "@switchboard-xyz/common": "^2.3.3", - "@switchboard-xyz/oracle": "latest", - "@switchboard-xyz/solana.js": "^2.5.0", + "@switchboard-xyz/common": "*", + "@switchboard-xyz/oracle": "*", + "@switchboard-xyz/solana.js": "*", "chalk": "^4.1.2", "dotenv": "^16.0.1", "yargs": "^17.5.1" diff --git a/examples/feeds/02_spl_native/package.json b/examples/feeds/02_spl_native/package.json index 0f668fa14..9b56bea2f 100644 --- a/examples/feeds/02_spl_native/package.json +++ b/examples/feeds/02_spl_native/package.json @@ -17,9 +17,9 @@ "dependencies": { "@coral-xyz/anchor": "^0.28.0", "@solana/web3.js": "^1.77.3", - "@switchboard-xyz/common": "^2.3.3", - "@switchboard-xyz/oracle": "latest", - "@switchboard-xyz/solana.js": "^2.5.0" + "@switchboard-xyz/common": "*", + "@switchboard-xyz/oracle": "*", + "@switchboard-xyz/solana.js": "*" }, "devDependencies": { "@types/chai": "^4.3.0", diff --git a/examples/functions/01_basic_oracle/Anchor.toml b/examples/functions/01_basic_oracle/Anchor.toml index 71528b0f2..2cc23cce0 100644 --- a/examples/functions/01_basic_oracle/Anchor.toml +++ b/examples/functions/01_basic_oracle/Anchor.toml @@ -6,22 +6,22 @@ seeds = false skip-lint = false [programs.localnet] -basic_oracle = "APWppEwwfddbooTUijn3oAVnQH6jkLDxW4JrTMbBoQXJ" +basic_oracle = "8cagvrMvnhcVpVuAxYajqBGSrrjCbhJBL3954UjttwuJ" [programs.devnet] -basic_oracle = "APWppEwwfddbooTUijn3oAVnQH6jkLDxW4JrTMbBoQXJ" +basic_oracle = "8cagvrMvnhcVpVuAxYajqBGSrrjCbhJBL3954UjttwuJ" [provider] # cluster = "Localnet" # wallet = "~/.config/solana/id.json" -# cluster = "https://api.devnet.solana.com" -# wallet = "~/switchboard_environments_v2/devnet/upgrade_authority/upgrade_authority.json" -cluster = "https://api.mainnet-beta.solana.com" -wallet = "~/switchboard_environments_v2/mainnet/upgrade_authority/upgrade_authority.json" +cluster = "https://api.devnet.solana.com" +wallet = "~/switchboard_environments_v2/devnet/upgrade_authority/upgrade_authority.json" +# cluster = "https://api.mainnet-beta.solana.com" +# wallet = "~/switchboard_environments_v2/mainnet/upgrade_authority/upgrade_authority.json" [scripts] test = "pnpm exec ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" - +init = "pnpm exec tsx ./scripts/devnet.ts" [test.validator] url = "https://api.devnet.solana.com" @@ -48,4 +48,4 @@ address = "sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx" address = "5ExuoQR69trmKQfB95fDsUGsUrrChbGq9PFgt8qouncz" [[test.validator.clone]] # sb devnet attestation State -address = "5MFs7RGTjLi1wtKNBFRtuLipCkkjs4YQwRRU9sjnbQbS" \ No newline at end of file +address = "5MFs7RGTjLi1wtKNBFRtuLipCkkjs4YQwRRU9sjnbQbS" diff --git a/examples/functions/01_basic_oracle/Cargo.lock b/examples/functions/01_basic_oracle/Cargo.lock index 8ca881c62..5d2f3846c 100644 --- a/examples/functions/01_basic_oracle/Cargo.lock +++ b/examples/functions/01_basic_oracle/Cargo.lock @@ -103,64 +103,58 @@ dependencies = [ [[package]] name = "anchor-attribute-access-control" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa5be5b72abea167f87c868379ba3c2be356bfca9e6f474fd055fa0f7eeb4f2" +checksum = "e5f619f1d04f53621925ba8a2e633ba5a6081f2ae14758cbb67f38fd823e0a3e" dependencies = [ "anchor-syn", - "anyhow", "proc-macro2 1.0.63", "quote 1.0.29", - "regex", "syn 1.0.109", ] [[package]] name = "anchor-attribute-account" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f468970344c7c9f9d03b4da854fd7c54f21305059f53789d0045c1dd803f0018" +checksum = "e7f2a3e1df4685f18d12a943a9f2a7456305401af21a07c9fe076ef9ecd6e400" dependencies = [ "anchor-syn", - "anyhow", "bs58 0.5.0", "proc-macro2 1.0.63", "quote 1.0.29", - "rustversion", "syn 1.0.109", ] [[package]] name = "anchor-attribute-constant" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59948e7f9ef8144c2aefb3f32a40c5fce2798baeec765ba038389e82301017ef" +checksum = "9423945cb55627f0b30903288e78baf6f62c6c8ab28fb344b6b25f1ffee3dca7" dependencies = [ "anchor-syn", - "proc-macro2 1.0.63", + "quote 1.0.29", "syn 1.0.109", ] [[package]] name = "anchor-attribute-error" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc753c9d1c7981cb8948cf7e162fb0f64558999c0413058e2d43df1df5448086" +checksum = "93ed12720033cc3c3bf3cfa293349c2275cd5ab99936e33dd4bf283aaad3e241" dependencies = [ "anchor-syn", - "proc-macro2 1.0.63", "quote 1.0.29", "syn 1.0.109", ] [[package]] name = "anchor-attribute-event" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38b4e172ba1b52078f53fdc9f11e3dc0668ad27997838a0aad2d148afac8c97" +checksum = "eef4dc0371eba2d8c8b54794b0b0eb786a234a559b77593d6f80825b6d2c77a2" dependencies = [ "anchor-syn", - "anyhow", "proc-macro2 1.0.63", "quote 1.0.29", "syn 1.0.109", @@ -168,22 +162,20 @@ dependencies = [ [[package]] name = "anchor-attribute-program" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eebd21543606ab61e2d83d9da37d24d3886a49f390f9c43a1964735e8c0f0d5" +checksum = "b18c4f191331e078d4a6a080954d1576241c29c56638783322a18d308ab27e4f" dependencies = [ "anchor-syn", - "anyhow", - "proc-macro2 1.0.63", "quote 1.0.29", "syn 1.0.109", ] [[package]] name = "anchor-client" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8434a6bf33efba0c93157f7fa2fafac658cb26ab75396886dcedd87c2a8ad445" +checksum = "cb48c4a7911038da546dc752655a29fa49f6bd50ebc1edca218bac8da1012acd" dependencies = [ "anchor-lang", "anyhow", @@ -200,12 +192,23 @@ dependencies = [ [[package]] name = "anchor-derive-accounts" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec4720d899b3686396cced9508f23dab420f1308344456ec78ef76f98fda42af" +checksum = "5de10d6e9620d3bcea56c56151cad83c5992f50d5960b3a9bebc4a50390ddc3c" dependencies = [ "anchor-syn", - "anyhow", + "quote 1.0.29", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-serde" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e2e5be518ec6053d90a2a7f26843dbee607583c779e6c8395951b9739bdfbe" +dependencies = [ + "anchor-syn", + "borsh-derive-internal 0.10.3", "proc-macro2 1.0.63", "quote 1.0.29", "syn 1.0.109", @@ -213,9 +216,9 @@ dependencies = [ [[package]] name = "anchor-derive-space" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f495e85480bd96ddeb77b71d499247c7d4e8b501e75ecb234e9ef7ae7bd6552a" +checksum = "1ecc31d19fa54840e74b7a979d44bcea49d70459de846088a1d71e87ba53c419" dependencies = [ "proc-macro2 1.0.63", "quote 1.0.29", @@ -224,9 +227,9 @@ dependencies = [ [[package]] name = "anchor-lang" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d2d4b20100f1310a774aba3471ef268e5c4ba4d5c28c0bbe663c2658acbc414" +checksum = "35da4785497388af0553586d55ebdc08054a8b1724720ef2749d313494f2b8ad" dependencies = [ "anchor-attribute-access-control", "anchor-attribute-account", @@ -235,6 +238,7 @@ dependencies = [ "anchor-attribute-event", "anchor-attribute-program", "anchor-derive-accounts", + "anchor-derive-serde", "anchor-derive-space", "arrayref", "base64 0.13.1", @@ -248,9 +252,9 @@ dependencies = [ [[package]] name = "anchor-spl" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78f860599da1c2354e7234c768783049eb42e2f54509ecfc942d2e0076a2da7b" +checksum = "6c4fd6e43b2ca6220d2ef1641539e678bfc31b6cc393cf892b373b5997b6a39a" dependencies = [ "anchor-lang", "solana-program", @@ -261,9 +265,9 @@ dependencies = [ [[package]] name = "anchor-syn" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a125e4b0cc046cfec58f5aa25038e34cf440151d58f0db3afc55308251fe936d" +checksum = "d9101b84702fed2ea57bd22992f75065da5648017135b844283a2f6d74f27825" dependencies = [ "anyhow", "bs58 0.5.0", @@ -575,9 +579,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" @@ -834,9 +838,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" dependencies = [ "bytemuck_derive", ] @@ -969,9 +973,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" dependencies = [ "crossbeam-utils", ] @@ -1193,6 +1197,19 @@ dependencies = [ "syn 2.0.23", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core 0.9.8", +] + [[package]] name = "data-encoding" version = "2.4.0" @@ -1409,6 +1426,15 @@ dependencies = [ "serde", ] +[[package]] +name = "erased-serde" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +dependencies = [ + "serde", +] + [[package]] name = "errno" version = "0.3.1" @@ -1684,6 +1710,12 @@ dependencies = [ "ahash 0.8.3", ] +[[package]] +name = "hashbrown" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" + [[package]] name = "heck" version = "0.3.3" @@ -1897,9 +1929,9 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.6" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730" +checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" dependencies = [ "console", "instant", @@ -1991,6 +2023,15 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -2082,9 +2123,12 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +dependencies = [ + "value-bag", +] [[package]] name = "memchr" @@ -2176,16 +2220,15 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ "bitflags", "cfg-if", "libc", "memoffset 0.7.1", "pin-utils", - "static_assertions", ] [[package]] @@ -2275,6 +2318,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "num-derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.29", + "syn 2.0.23", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -2329,41 +2383,41 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.11" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" dependencies = [ - "num_enum_derive 0.5.11", + "num_enum_derive 0.6.1", ] [[package]] name = "num_enum" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +checksum = "683751d591e6d81200c39fb0d1032608b77724f34114db54f571ff1317b337c0" dependencies = [ - "num_enum_derive 0.6.1", + "num_enum_derive 0.7.1", ] [[package]] name = "num_enum_derive" -version = "0.5.11" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 1.1.3", "proc-macro2 1.0.63", "quote 1.0.29", - "syn 1.0.109", + "syn 2.0.23", ] [[package]] name = "num_enum_derive" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 1.1.3", "proc-macro2 1.0.63", "quote 1.0.29", "syn 2.0.23", @@ -2553,9 +2607,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.4.2" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f32154ba0af3a075eefa1eda8bb414ee928f62303a54ea85b8d6638ff1a6ee9e" +checksum = "3bccab0e7fd7cc19f820a1c8c91720af652d0c88dc9664dd72aef2614f04af3b" [[package]] name = "ppv-lite86" @@ -2574,12 +2628,12 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" dependencies = [ - "once_cell", - "toml_edit", + "thiserror", + "toml", ] [[package]] @@ -2649,9 +2703,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.9.4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31999cfc7927c4e212e60fd50934ab40e8e8bfd2d493d6095d2d306bc0764d9" +checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863" dependencies = [ "bytes", "rand 0.8.5", @@ -2880,7 +2934,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91" dependencies = [ "async-compression", - "base64 0.21.2", + "base64 0.21.5", "bytes", "encoding_rs", "futures-core", @@ -2959,23 +3013,23 @@ dependencies = [ [[package]] name = "rpassword" -version = "7.2.0" +version = "7.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322" +checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" dependencies = [ "libc", "rtoolbox", - "winapi", + "windows-sys 0.48.0", ] [[package]] name = "rtoolbox" -version = "0.0.1" +version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034e22c514f5c0cb8a10ff341b9b048b5ceb21591f31c8f44c43b960f9b3524a" +checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e" dependencies = [ "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -3070,7 +3124,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.5", ] [[package]] @@ -3194,6 +3248,15 @@ dependencies = [ "syn 2.0.23", ] +[[package]] +name = "serde_fmt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" +dependencies = [ + "serde", +] + [[package]] name = "serde_json" version = "1.0.100" @@ -3369,12 +3432,12 @@ dependencies = [ [[package]] name = "solana-account-decoder" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298accbe9b2bffc391081b94f30ec3dd5bac053bfcd09aa78c06f1f87d33ec1e" +checksum = "5d8ea963f393c09376f21f7f5217d5701a18d65c821a68337188b6cf9c1255db" dependencies = [ "Inflector", - "base64 0.21.2", + "base64 0.21.5", "bincode", "bs58 0.4.0", "bv", @@ -3387,20 +3450,21 @@ dependencies = [ "solana-sdk", "spl-token", "spl-token-2022", + "spl-token-metadata-interface", "thiserror", "zstd", ] [[package]] name = "solana-address-lookup-table-program" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c026db45d6d8a21afe308fab93a40c77d21cb7a0f1f2fe4b99bb7bbcd7028ed7" +checksum = "5c284096b2d4595b13f61004142c6caff4f3dc40ba77dbd5f4071d67c256e15c" dependencies = [ "bincode", "bytemuck", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", "rustc_version", "serde", @@ -3414,9 +3478,9 @@ dependencies = [ [[package]] name = "solana-clap-utils" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d27f6ef67bb0519da2d7c7dd9f65c8e447a9a1c8330bb032b78d80712472fefd" +checksum = "b4371b20d9dff6a0e769cd103385e7c257d511efec11efd94c65ab52a39255e2" dependencies = [ "chrono", "clap 2.34.0", @@ -3432,9 +3496,9 @@ dependencies = [ [[package]] name = "solana-client" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13cf67b2f89d8ce5ce0b8c75baac79dc10b082cf096b149146724182db5506cf" +checksum = "78ee4db75f979886731e603f7bd22eeb3386cd1477a7592931e21623326da83b" dependencies = [ "async-trait", "bincode", @@ -3465,9 +3529,9 @@ dependencies = [ [[package]] name = "solana-config-program" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4065170279a38c1013fcf9c1776579914e7c30edb831f28dfd59f9d939d90f63" +checksum = "ae9df684ad70f3e3cb716a085652b545a64dfbc9299c59f768112ec69d4f4392" dependencies = [ "bincode", "chrono", @@ -3479,9 +3543,9 @@ dependencies = [ [[package]] name = "solana-connection-cache" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a98001f5293720075b52faa7e05c78c33ffdcc23ed7dea2cad102ed4823d624" +checksum = "c58c2e8007f2fd5ae0302ccaa7df72bdb6b1b40fd9f4b6c67f5e928dc58d9f35" dependencies = [ "async-trait", "bincode", @@ -3500,9 +3564,9 @@ dependencies = [ [[package]] name = "solana-frozen-abi" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee2b96d4150d9ebf55e903014bc332ac64c642837d7f1e6f7b911d709331380" +checksum = "9ab680d7d65fcecdea832cadb063fc3898121bc56cab15aee54f2c5db71af535" dependencies = [ "ahash 0.8.3", "blake3", @@ -3533,9 +3597,9 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942534eb972f955ed186175495654cabece6261a8ac3211e5791440d40a1ed96" +checksum = "b02411fefc004154edf3fe61cedb1dfb26ef82b659148b0a4b21ce3184d40ebc" dependencies = [ "proc-macro2 1.0.63", "quote 1.0.29", @@ -3545,9 +3609,9 @@ dependencies = [ [[package]] name = "solana-logger" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1339e1a179e2465e97fd89c2f70d5f00c5644f36c0e547b8ecda414c748dfc2c" +checksum = "f9c7f0c4504c512f93aed16fb07449cafa5fa0c54ef7cfff6f377b2a5ed34553" dependencies = [ "env_logger", "lazy_static", @@ -3556,9 +3620,9 @@ dependencies = [ [[package]] name = "solana-measure" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b3feab384868634ea5d7a12fc62c001d5785b6a352b7903ad13edbb7d3043f3" +checksum = "ceb54a32ad5125ed514c058639ac86508efcffc2412f713e3140eb70291d9843" dependencies = [ "log", "solana-sdk", @@ -3566,9 +3630,9 @@ dependencies = [ [[package]] name = "solana-metrics" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31c1f2569ea75ee9aa73eedb948b17eabc468e6cd5c1aee4d9cdfaffb0f3d33" +checksum = "ef674e1c16731541af6f58515ebdae519f68d374a3018675dc9ee3480b4a640e" dependencies = [ "crossbeam-channel", "gethostname", @@ -3580,9 +3644,9 @@ dependencies = [ [[package]] name = "solana-net-utils" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "725a2f7335cc7ec5be356baaf44b0d3211f996b174e2a3b340227e700d26fc55" +checksum = "a39ab5b49d50c50411fe1990b097458dd3d23aee1753db9b13f69a2f946409f5" dependencies = [ "bincode", "clap 3.2.25", @@ -3602,9 +3666,9 @@ dependencies = [ [[package]] name = "solana-perf" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2048b4890677ec4287a205a0f53d6a9bf2bdbcc7046aeb665b2714e3c1a4e655" +checksum = "710431ce6bc8a070c3b54999f9602b8b4c94358836615e89e357114ea0ae1fe5" dependencies = [ "ahash 0.8.3", "bincode", @@ -3629,16 +3693,16 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f81c59ed0b65b403cc5db459dd1214dfab89ccd3ce20aadf98102b072d08562" +checksum = "aedf18ad0e74ce21123eb94c45d8b469d280a6a3e4f1bf6411fc4ca8fc7c2eac" dependencies = [ "ark-bn254", "ark-ec", "ark-ff", "ark-serialize", "array-bytes", - "base64 0.21.2", + "base64 0.21.5", "bincode", "bitflags", "blake3", @@ -3660,7 +3724,7 @@ dependencies = [ "log", "memoffset 0.9.0", "num-bigint 0.4.3", - "num-derive", + "num-derive 0.3.3", "num-traits", "parking_lot 0.12.1", "rand 0.7.3", @@ -3684,18 +3748,18 @@ dependencies = [ [[package]] name = "solana-program-runtime" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc8624325d63e9a643385739c53315d8768aff689dfa9ad06ed1c67aac163ab2" +checksum = "d9e3ff03078645ddd91e2a3eb2d58a90a5a6c9d7e8c2b9c2b3511f24ea03b711" dependencies = [ - "base64 0.21.2", + "base64 0.21.5", "bincode", "eager", "enum-iterator", "itertools", "libc", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", "percentage", "rand 0.7.3", @@ -3712,9 +3776,9 @@ dependencies = [ [[package]] name = "solana-pubsub-client" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e10c8caee33c14b74fa2e76f8d8638364303bbf4439e284fddf66b7e3a5acb" +checksum = "8c7d115473531dbc447989e3e6eb24a418bf3c0b7ffb86da17c4a1271d1ce553" dependencies = [ "crossbeam-channel", "futures-util", @@ -3737,9 +3801,9 @@ dependencies = [ [[package]] name = "solana-quic-client" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7173c8eb7b20a1c04838655760ba36e5a4398dc9cd16115a5321c7a56e6a34ff" +checksum = "bca1af43f5b44321e2a5f48798d07ade968c7d95c3191ef2f8e167a481ed4d37" dependencies = [ "async-mutex", "async-trait", @@ -3765,9 +3829,9 @@ dependencies = [ [[package]] name = "solana-rayon-threadlimit" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe5195e62d9457233f97f30aa678f71b1aaed2200a170e63f0da7d9a3d124aa3" +checksum = "cb5a290bb5b316654d165326c1ed22cf15a40559523824097308913cce2dcad7" dependencies = [ "lazy_static", "num_cpus", @@ -3775,14 +3839,14 @@ dependencies = [ [[package]] name = "solana-remote-wallet" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04b5777335473d24b6edf9ca36129b1f8e07ba34de18e2b8d6285a4e3473260c" +checksum = "a082793597a5467271d35cbee5e3782e42a0b52849521f293b6bc07f9514d018" dependencies = [ "console", "dialoguer", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", "parking_lot 0.12.1", "qstring", @@ -3794,12 +3858,12 @@ dependencies = [ [[package]] name = "solana-rpc-client" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d34afb705efdf62ad1a911beffe3c6d599eab2125bd07460e85a424636cb54" +checksum = "b6ed31f6dd0546a92daf7493c94b602e6c06e59b474d5a81559ff88d6d3e8afa" dependencies = [ "async-trait", - "base64 0.21.2", + "base64 0.21.5", "bincode", "bs58 0.4.0", "indicatif", @@ -3820,11 +3884,11 @@ dependencies = [ [[package]] name = "solana-rpc-client-api" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e28db9b3748bfe7367ef9e9b968be1643f63ab9c360e89681d426d036cf69a" +checksum = "e846fb99c6aa3d044cb556f40156a585dd3f4cb1e416b5b8319028d3f731b6a8" dependencies = [ - "base64 0.21.2", + "base64 0.21.5", "bs58 0.4.0", "jsonrpc-core", "reqwest", @@ -3842,9 +3906,9 @@ dependencies = [ [[package]] name = "solana-rpc-client-nonce-utils" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27c9c9f034bf3c931441a0fbb528b8e3bf417a32b70546e5fa0c00cd78559ff5" +checksum = "cc5ac3f71c723bf061e684c1bcf9be29b99d07fd6be54cf9e12f1cc1629d4f74" dependencies = [ "clap 2.34.0", "solana-clap-utils", @@ -3855,12 +3919,12 @@ dependencies = [ [[package]] name = "solana-sdk" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23dbf6da55a2d191956c693d8490dc809799822536aceb11309043e9b622079" +checksum = "d6aea1e7067980ca1ef57a31c498413547b82aa392d9e7ec5539968f1a8dec1c" dependencies = [ "assert_matches", - "base64 0.21.2", + "base64 0.21.5", "bincode", "bitflags", "borsh 0.10.3", @@ -3880,7 +3944,7 @@ dependencies = [ "libsecp256k1", "log", "memmap2", - "num-derive", + "num-derive 0.3.3", "num-traits", "num_enum 0.6.1", "pbkdf2 0.11.0", @@ -3908,9 +3972,9 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7d686e405694cd6510cd77bb87d0eeda64ad3df08d3293278ba47ca78b8e5e" +checksum = "dbca599523925e4c55e0326d93eef0a8e1918df5f93897811abf3f5972e21bec" dependencies = [ "bs58 0.4.0", "proc-macro2 1.0.63", @@ -3921,9 +3985,9 @@ dependencies = [ [[package]] name = "solana-streamer" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e40e74d6ae01dd21dc1a93a2213f8d7e04aea69079092a131ad5bd2d54aa16bc" +checksum = "2147a8042ec522d31a5ec67ef06000d7c4d528d7ce49a2e5225687fb5ad08ea8" dependencies = [ "async-channel", "bytes", @@ -3954,9 +4018,9 @@ dependencies = [ [[package]] name = "solana-thin-client" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f3a1dae21f002f2d35ddfcc09fb528bc52936bb9fe4aea7bb46b1361998ed7" +checksum = "8af1069859646695b53b88cf071ba3c2ce49f0fbe9b19014440676e1869704f5" dependencies = [ "bincode", "log", @@ -3969,9 +4033,9 @@ dependencies = [ [[package]] name = "solana-tpu-client" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fffd371a68959dbbbb073198cd93121586da924a8dc493bd624a5ddf40a6742" +checksum = "d9bc57c809b5ee98570bd0981c3ecce339d4053f8473ab2d57a9487ad3aea5af" dependencies = [ "async-trait", "bincode", @@ -3994,14 +4058,14 @@ dependencies = [ [[package]] name = "solana-transaction-status" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeb3b1a35fc4718e758851670a959bb4736a8825f56c7ebfcd6eec892cbd200a" +checksum = "f225ca544e1005918608bfe67f97c1cfdfe43bb6ab41e0bd77491258a7e5e8f8" dependencies = [ "Inflector", - "base64 0.21.2", + "base64 0.21.5", "bincode", - "borsh 0.9.3", + "borsh 0.10.3", "bs58 0.4.0", "lazy_static", "log", @@ -4020,9 +4084,9 @@ dependencies = [ [[package]] name = "solana-udp-client" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05fd1c52102c716767d32a6936843b0505ad61bad958b34bcff513fe609611e7" +checksum = "be1dbf725b5e31863f34553c1333e8d8e098c6259bbed433630022aa59e9a175" dependencies = [ "async-trait", "solana-connection-cache", @@ -4035,9 +4099,9 @@ dependencies = [ [[package]] name = "solana-version" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4f9750ce47f0a431338121a3247bd29665d6da5a8ebde8c5320503c98d8adc" +checksum = "cc8ac5da4f0044a857cb35bf0a146e76400541fce72f0638b9377fd368cf2da0" dependencies = [ "log", "rustc_version", @@ -4051,13 +4115,13 @@ dependencies = [ [[package]] name = "solana-vote-program" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258b4c3e62faaed0cd864b02760659e45fb4431a287ee0088ae79af891ae4786" +checksum = "ee3c171647345a050eaf80846d99f888c55c2bcbdd0297dfae38597950ca6054" dependencies = [ "bincode", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", "rustc_version", "serde", @@ -4073,12 +4137,12 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2d04eecf3a7438c95db28b57437e94f09a1e60377183d9bea0c9db84506f504" +checksum = "b8d5a0aa72c38c45b134e6fc008569fe1b0882c7cff5fceb7e42c0406925d3e5" dependencies = [ "aes-gcm-siv", - "base64 0.21.2", + "base64 0.21.5", "bincode", "bytemuck", "byteorder", @@ -4087,7 +4151,7 @@ dependencies = [ "itertools", "lazy_static", "merlin", - "num-derive", + "num-derive 0.3.3", "num-traits", "rand 0.7.3", "serde", @@ -4102,9 +4166,9 @@ dependencies = [ [[package]] name = "solana_rbpf" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3082ec3a1d4ef7879eb5b84916d5acde057abd59733eec3647e0ab8885283ef" +checksum = "17d4ba1e58947346e360fabde0697029d36ba83c42f669199b16a8931313cf29" dependencies = [ "byteorder", "combine", @@ -4137,13 +4201,13 @@ dependencies = [ [[package]] name = "spl-associated-token-account" -version = "1.1.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978dba3bcbe88d0c2c58366c254d9ea41c5f73357e72fc0bdee4d6b5fc99c8f4" +checksum = "385e31c29981488f2820b2022d8e731aae3b02e6e18e2fd854e4c9a94dc44fc3" dependencies = [ "assert_matches", - "borsh 0.9.3", - "num-derive", + "borsh 0.10.3", + "num-derive 0.4.1", "num-traits", "solana-program", "spl-token", @@ -4151,48 +4215,182 @@ dependencies = [ "thiserror", ] +[[package]] +name = "spl-discriminator" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cce5d563b58ef1bb2cdbbfe0dfb9ffdc24903b10ae6a4df2d8f425ece375033f" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator-derive", +] + +[[package]] +name = "spl-discriminator-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fadbefec4f3c678215ca72bd71862697bb06b41fd77c0088902dd3203354387b" +dependencies = [ + "quote 1.0.29", + "spl-discriminator-syn", + "syn 2.0.23", +] + +[[package]] +name = "spl-discriminator-syn" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e5f2044ca42c8938d54d1255ce599c79a1ffd86b677dfab695caa20f9ffc3f2" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.29", + "sha2 0.10.7", + "syn 2.0.23", + "thiserror", +] + [[package]] name = "spl-memo" -version = "3.0.1" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0dc6f70db6bacea7ff25870b016a65ba1d1b6013536f08e4fd79a8f9005325" +checksum = "f0f180b03318c3dbab3ef4e1e4d46d5211ae3c780940dd0a28695aba4b59a75a" dependencies = [ "solana-program", ] +[[package]] +name = "spl-pod" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2881dddfca792737c0706fa0175345ab282b1b0879c7d877bad129645737c079" +dependencies = [ + "borsh 0.10.3", + "bytemuck", + "solana-program", + "solana-zk-token-sdk", + "spl-program-error", +] + +[[package]] +name = "spl-program-error" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "249e0318493b6bcf27ae9902600566c689b7dfba9f1bdff5893e92253374e78c" +dependencies = [ + "num-derive 0.4.1", + "num-traits", + "solana-program", + "spl-program-error-derive", + "thiserror", +] + +[[package]] +name = "spl-program-error-derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5269c8e868da17b6552ef35a51355a017bd8e0eae269c201fef830d35fa52c" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.29", + "sha2 0.10.7", + "syn 2.0.23", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062e148d3eab7b165582757453632ffeef490c02c86a48bfdb4988f63eefb3b9" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + [[package]] name = "spl-token" -version = "3.5.0" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e85e168a785e82564160dcb87b2a8e04cee9bfd1f4d488c729d53d6a4bd300d" +checksum = "08459ba1b8f7c1020b4582c4edf0f5c7511a5e099a7a97570c9698d4f2337060" dependencies = [ "arrayref", "bytemuck", - "num-derive", + "num-derive 0.3.3", "num-traits", - "num_enum 0.5.11", + "num_enum 0.6.1", "solana-program", "thiserror", ] [[package]] name = "spl-token-2022" -version = "0.6.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0043b590232c400bad5ee9eb983ced003d15163c4c5d56b090ac6d9a57457b47" +checksum = "e4abf34a65ba420584a0c35f3903f8d727d1f13ababbdc3f714c6b065a686e86" dependencies = [ "arrayref", "bytemuck", - "num-derive", + "num-derive 0.4.1", "num-traits", - "num_enum 0.5.11", + "num_enum 0.7.1", "solana-program", "solana-zk-token-sdk", "spl-memo", + "spl-pod", "spl-token", + "spl-token-metadata-interface", + "spl-transfer-hook-interface", + "spl-type-length-value", "thiserror", ] +[[package]] +name = "spl-token-metadata-interface" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" +dependencies = [ + "borsh 0.10.3", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051d31803f873cabe71aec3c1b849f35248beae5d19a347d93a5c9cccc5d5a9b" +dependencies = [ + "arrayref", + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value", +] + +[[package]] +name = "spl-type-length-value" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a468e6f6371f9c69aae760186ea9f1a01c2908351b06a5e0026d21cfc4d7ecac" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -4224,36 +4422,114 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" [[package]] -name = "switchboard-common" -version = "0.8.18" +name = "sval" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15df12a8db7c216a04b4b438f90d50d5335cd38f161b56389c9f5c9d96d0873" + +[[package]] +name = "sval_buffer" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e80556bc8acea0446e574ce542ad6114a76a0237f28a842bc01ca3ea98f479" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d93d2259edb1d7b4316179f0a98c62e3ffc726f47ab200e07cfe382771f57b8" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532f7f882226f7a5a4656f5151224aaebf8217e0d539cb1595b831bace921343" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e03bd8aa0ae6ee018f7ae95c9714577687a4415bd1a5f19b26e34695f7e072" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_ref" +version = "2.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c9e28848b864786d8b1835f1f0c4c7e65190d9c17b246e5e21cc2457a70b176" +checksum = "75ed054f2fb8c2a0ab5d36c1ec57b412919700099fc5e32ad8e7a38b23e1a9e1" dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff191c4ff05b67e3844c161021427646cde5d6624597958be158357d9200586" +dependencies = [ + "serde", + "sval", + "sval_buffer", + "sval_fmt", +] + +[[package]] +name = "switchboard-common" +version = "0.11.0" +dependencies = [ + "async-trait", + "base64 0.21.5", "envy", + "futures", "getrandom 0.2.10", "hex", + "log", "serde", "serde_json", "sgx-quote", "sha2 0.10.7", + "sha3 0.10.8", ] [[package]] name = "switchboard-solana" -version = "0.28.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0213e971a7eb8910e228a473219e5eee3c799a3365cb33cf2ad482d58044ec4c" +version = "0.29.70" dependencies = [ "anchor-client", "anchor-lang", "anchor-spl", + "base64 0.21.5", "bincode", "bytemuck", "chrono", "cron", + "dashmap", + "futures", "hex", + "kv-log-macro", + "log", "rust_decimal", + "serde", + "serde_json", "sgx-quote", + "sha2 0.10.7", + "solana-account-decoder", "solana-address-lookup-table-program", "solana-client", "solana-program", @@ -4536,23 +4812,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_datetime" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" - -[[package]] -name = "toml_edit" -version = "0.19.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow", -] - [[package]] name = "tower-service" version = "0.3.2" @@ -4728,6 +4987,42 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" +[[package]] +name = "value-bag" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a72e1902dde2bd6441347de2b70b7f5d59bf157c6c62f0c44572607a1d55bbe" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ba39dc791ecb35baad371a3fc04c6eab688c04937d2e0ac6c22b612c0357bf" +dependencies = [ + "erased-serde", + "serde", + "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e06c10810a57bbf45778d023d432a50a1daa7d185991ae06bcfb6c654d0945" +dependencies = [ + "sval", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", +] + [[package]] name = "vec_map" version = "0.8.2" @@ -5055,15 +5350,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" -[[package]] -name = "winnow" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" -dependencies = [ - "memchr", -] - [[package]] name = "winreg" version = "0.10.1" diff --git a/examples/functions/01_basic_oracle/Cargo.toml b/examples/functions/01_basic_oracle/Cargo.toml index 9532b9a10..f298aab12 100644 --- a/examples/functions/01_basic_oracle/Cargo.toml +++ b/examples/functions/01_basic_oracle/Cargo.toml @@ -19,6 +19,6 @@ cpi = ["no-entrypoint"] default = [] [dependencies] -switchboard-solana = { version = "0.28.19", features = [] } -# switchboard-solana = { version = "0.28.19", path = "../../../rust/switchboard-solana" } +# switchboard-solana = { version = "0.28.43" } +switchboard-solana = { path = "../../../rust/switchboard-solana" } bytemuck = "^1" diff --git a/examples/functions/01_basic_oracle/package.json b/examples/functions/01_basic_oracle/package.json index 6ce9909cc..48d135400 100644 --- a/examples/functions/01_basic_oracle/package.json +++ b/examples/functions/01_basic_oracle/package.json @@ -15,7 +15,7 @@ "@coral-xyz/anchor": "^0.28.0", "@solana/spl-token": "^0.3.6", "@solana/web3.js": "^1.78.0", - "@switchboard-xyz/solana.js": "workspace:*" + "@switchboard-xyz/solana.js": "^" }, "devDependencies": { "@types/bn.js": "^5.1.0", @@ -26,4 +26,4 @@ "mocha": "^9.0.3", "ts-mocha": "^10.0.0" } -} +} \ No newline at end of file diff --git a/examples/functions/01_basic_oracle/scripts/devnet.ts b/examples/functions/01_basic_oracle/scripts/devnet.ts index 0aa01d737..82a5f7c34 100644 --- a/examples/functions/01_basic_oracle/scripts/devnet.ts +++ b/examples/functions/01_basic_oracle/scripts/devnet.ts @@ -5,7 +5,12 @@ import * as anchor from "@coral-xyz/anchor"; import { Connection, PublicKey } from "@solana/web3.js"; import * as sb from "@switchboard-xyz/solana.js"; -const functionPubkey = "Accb21tUCWocJea6Uk3DgrNZawgmKegDVeHw8cGMDPi5"; +const functionPubkey = "HL2jSHrxCprnmLHdY4rGSZ6pRGieBREcPHFbvzniYWYp"; +const routinePubkey = "ACcdtN6xVn1D82jH7fyK3F68CYXS6aVZTZ3NwYvrMuUt"; + +const PROGRAM_SEED = "BASICORACLE"; + +const ORACLE_SEED = "ORACLE_V1_SEED"; const rpcUrl = "https://api.devnet.solana.com"; @@ -28,12 +33,12 @@ async function main() { const payer = (program.provider as anchor.AnchorProvider).publicKey; const programStatePubkey = anchor.web3.PublicKey.findProgramAddressSync( - [Buffer.from("BASICORACLE")], + [Buffer.from(PROGRAM_SEED)], program.programId )[0]; const oraclePubkey = anchor.web3.PublicKey.findProgramAddressSync( - [Buffer.from("ORACLE_V1_SEED")], + [Buffer.from(ORACLE_SEED)], program.programId )[0]; @@ -55,7 +60,8 @@ async function main() { .setFunction({}) .accounts({ program: programStatePubkey, - function: new PublicKey(functionPubkey), + switchboardFunction: new PublicKey(functionPubkey), + switchboardRoutine: new PublicKey(routinePubkey), authority: payer, }) .rpc(); diff --git a/examples/functions/01_basic_oracle/src/actions/initialize.rs b/examples/functions/01_basic_oracle/src/actions/initialize.rs index 2595628d9..24220a0e9 100644 --- a/examples/functions/01_basic_oracle/src/actions/initialize.rs +++ b/examples/functions/01_basic_oracle/src/actions/initialize.rs @@ -36,18 +36,18 @@ impl Initialize<'_> { pub fn validate( &self, _ctx: &Context, - _params: &InitializeParams, + _params: &InitializeParams ) -> anchor_lang::Result<()> { Ok(()) } pub fn actuate(ctx: &Context, _params: &InitializeParams) -> anchor_lang::Result<()> { let program = &mut ctx.accounts.program.load_init()?; - program.bump = *ctx.bumps.get("program").unwrap(); + program.bump = ctx.bumps.program; program.authority = ctx.accounts.authority.key(); let oracle = &mut ctx.accounts.oracle.load_init()?; - oracle.bump = *ctx.bumps.get("oracle").unwrap(); + oracle.bump = ctx.bumps.oracle; Ok(()) } } diff --git a/examples/functions/01_basic_oracle/src/actions/mod.rs b/examples/functions/01_basic_oracle/src/actions/mod.rs index d2a9b9e16..6dde55a96 100644 --- a/examples/functions/01_basic_oracle/src/actions/mod.rs +++ b/examples/functions/01_basic_oracle/src/actions/mod.rs @@ -6,6 +6,3 @@ pub use refresh_prices::*; pub mod set_function; pub use set_function::*; - -pub mod trigger_function; -pub use trigger_function::*; diff --git a/examples/functions/01_basic_oracle/src/actions/refresh_prices.rs b/examples/functions/01_basic_oracle/src/actions/refresh_prices.rs index 22ee82418..8bd168189 100644 --- a/examples/functions/01_basic_oracle/src/actions/refresh_prices.rs +++ b/examples/functions/01_basic_oracle/src/actions/refresh_prices.rs @@ -10,13 +10,14 @@ pub struct RefreshPrices<'info> { pub oracle: AccountLoader<'info, MyOracleState>, // We use this to verify the functions enclave state + pub switchboard_function: AccountLoader<'info, FunctionAccountData>, #[account( - constraint = - function.load()?.validate( - &enclave_signer.to_account_info() - )? @ BasicOracleError::FunctionValidationFailed + // constraint = switchboard_routine.validate_signer( + // switchboard_function.to_account_info().as_ref(), + // enclave_signer.to_account_info().as_ref() + // )? )] - pub function: AccountLoader<'info, FunctionAccountData>, + pub switchboard_routine: Box>, pub enclave_signer: Signer<'info>, } @@ -29,7 +30,7 @@ impl RefreshPrices<'_> { pub fn validate( &self, _ctx: &Context, - _params: &RefreshPricesParams, + _params: &RefreshPricesParams ) -> anchor_lang::Result<()> { Ok(()) } diff --git a/examples/functions/01_basic_oracle/src/actions/set_function.rs b/examples/functions/01_basic_oracle/src/actions/set_function.rs index e59de4f9a..f31dd9264 100644 --- a/examples/functions/01_basic_oracle/src/actions/set_function.rs +++ b/examples/functions/01_basic_oracle/src/actions/set_function.rs @@ -5,13 +5,14 @@ use crate::*; pub struct SetFunction<'info> { #[account( mut, - seeds = [PROGRAM_SEED], - bump = program.load()?.bump, + // seeds = [PROGRAM_SEED], + // bump = program.load()?.bump, has_one = authority )] pub program: AccountLoader<'info, MyProgramState>, - pub function: AccountLoader<'info, FunctionAccountData>, + pub switchboard_function: AccountLoader<'info, FunctionAccountData>, + pub switchboard_routine: Box>, pub authority: Signer<'info>, } @@ -29,8 +30,9 @@ impl SetFunction<'_> { } pub fn actuate(ctx: &Context, _params: &SetFunctionParams) -> anchor_lang::Result<()> { - let program = &mut ctx.accounts.program.load_init()?; - program.function = ctx.accounts.function.key(); + let program = &mut ctx.accounts.program.load_mut()?; + program.switchboard_function = ctx.accounts.switchboard_function.key(); + program.switchboard_routine = ctx.accounts.switchboard_routine.key(); Ok(()) } } diff --git a/examples/functions/01_basic_oracle/src/actions/trigger_function.rs b/examples/functions/01_basic_oracle/src/actions/trigger_function.rs deleted file mode 100644 index 53c9b6cc7..000000000 --- a/examples/functions/01_basic_oracle/src/actions/trigger_function.rs +++ /dev/null @@ -1,47 +0,0 @@ -use crate::*; -use switchboard_solana::attestation_program::instructions::function_trigger::FunctionTrigger; -use switchboard_solana::SWITCHBOARD_ATTESTATION_PROGRAM_ID; - -#[derive(Accounts)] -#[instruction(params: TriggerFunctionParams)] // rpc parameters hint -pub struct TriggerFunction<'info> { - #[account( - has_one = authority, - has_one = attestation_queue, - )] - pub function: AccountLoader<'info, FunctionAccountData>, - - pub attestation_queue: AccountLoader<'info, AttestationQueueAccountData>, - - pub authority: Signer<'info>, - - /// CHECK: address is explicit - #[account(address = SWITCHBOARD_ATTESTATION_PROGRAM_ID)] - pub attestation_program: AccountInfo<'info>, -} - -#[derive(Clone, AnchorSerialize, AnchorDeserialize)] -pub struct TriggerFunctionParams {} - -impl TriggerFunction<'_> { - pub fn validate( - &self, - _ctx: &Context, - _params: &TriggerFunctionParams, - ) -> anchor_lang::Result<()> { - Ok(()) - } - - pub fn actuate( - ctx: &Context, - _params: &TriggerFunctionParams, - ) -> anchor_lang::Result<()> { - FunctionTrigger { - function: ctx.accounts.function.to_account_info(), - authority: ctx.accounts.authority.to_account_info(), - attestation_queue: ctx.accounts.attestation_queue.to_account_info(), - } - .invoke(ctx.accounts.attestation_program.clone())?; - Ok(()) - } -} diff --git a/examples/functions/01_basic_oracle/src/lib.rs b/examples/functions/01_basic_oracle/src/lib.rs index a07db0fe3..8fad8ad67 100644 --- a/examples/functions/01_basic_oracle/src/lib.rs +++ b/examples/functions/01_basic_oracle/src/lib.rs @@ -12,7 +12,7 @@ pub use model::*; pub mod utils; pub use utils::*; -declare_id!("EF68PJkRqQu2VthTSy19kg6TWynMtRmLpxcMDKEdLC8t"); +declare_id!("8cagvrMvnhcVpVuAxYajqBGSrrjCbhJBL3954UjttwuJ"); pub const PROGRAM_SEED: &[u8] = b"BASICORACLE"; @@ -30,14 +30,6 @@ pub mod basic_oracle { Initialize::actuate(&ctx, ¶ms) } - #[access_control(ctx.accounts.validate(&ctx, ¶ms))] - pub fn refresh_oracles( - ctx: Context, - params: RefreshPricesParams, - ) -> anchor_lang::Result<()> { - RefreshPrices::actuate(&ctx, ¶ms) - } - #[access_control(ctx.accounts.validate(&ctx, ¶ms))] pub fn set_function( ctx: Context, @@ -47,10 +39,10 @@ pub mod basic_oracle { } #[access_control(ctx.accounts.validate(&ctx, ¶ms))] - pub fn trigger_function( - ctx: Context, - params: TriggerFunctionParams, + pub fn refresh_oracles( + ctx: Context, + params: RefreshPricesParams, ) -> anchor_lang::Result<()> { - TriggerFunction::actuate(&ctx, ¶ms) + RefreshPrices::actuate(&ctx, ¶ms) } } diff --git a/examples/functions/01_basic_oracle/src/model.rs b/examples/functions/01_basic_oracle/src/model.rs index 0a6b8778f..1075ba7fe 100644 --- a/examples/functions/01_basic_oracle/src/model.rs +++ b/examples/functions/01_basic_oracle/src/model.rs @@ -5,7 +5,8 @@ use bytemuck::{Pod, Zeroable}; pub struct MyProgramState { pub bump: u8, pub authority: Pubkey, - pub function: Pubkey, + pub switchboard_function: Pubkey, + pub switchboard_routine: Pubkey, } #[repr(packed)] diff --git a/examples/functions/01_basic_oracle/switchboard-function/Cargo.lock b/examples/functions/01_basic_oracle/switchboard-function/Cargo.lock index 9b829883f..45ada1688 100644 --- a/examples/functions/01_basic_oracle/switchboard-function/Cargo.lock +++ b/examples/functions/01_basic_oracle/switchboard-function/Cargo.lock @@ -103,64 +103,58 @@ dependencies = [ [[package]] name = "anchor-attribute-access-control" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa5be5b72abea167f87c868379ba3c2be356bfca9e6f474fd055fa0f7eeb4f2" +checksum = "e5f619f1d04f53621925ba8a2e633ba5a6081f2ae14758cbb67f38fd823e0a3e" dependencies = [ "anchor-syn", - "anyhow", "proc-macro2 1.0.66", "quote 1.0.32", - "regex", "syn 1.0.109", ] [[package]] name = "anchor-attribute-account" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f468970344c7c9f9d03b4da854fd7c54f21305059f53789d0045c1dd803f0018" +checksum = "e7f2a3e1df4685f18d12a943a9f2a7456305401af21a07c9fe076ef9ecd6e400" dependencies = [ "anchor-syn", - "anyhow", "bs58 0.5.0", "proc-macro2 1.0.66", "quote 1.0.32", - "rustversion", "syn 1.0.109", ] [[package]] name = "anchor-attribute-constant" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59948e7f9ef8144c2aefb3f32a40c5fce2798baeec765ba038389e82301017ef" +checksum = "9423945cb55627f0b30903288e78baf6f62c6c8ab28fb344b6b25f1ffee3dca7" dependencies = [ "anchor-syn", - "proc-macro2 1.0.66", + "quote 1.0.32", "syn 1.0.109", ] [[package]] name = "anchor-attribute-error" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc753c9d1c7981cb8948cf7e162fb0f64558999c0413058e2d43df1df5448086" +checksum = "93ed12720033cc3c3bf3cfa293349c2275cd5ab99936e33dd4bf283aaad3e241" dependencies = [ "anchor-syn", - "proc-macro2 1.0.66", "quote 1.0.32", "syn 1.0.109", ] [[package]] name = "anchor-attribute-event" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38b4e172ba1b52078f53fdc9f11e3dc0668ad27997838a0aad2d148afac8c97" +checksum = "eef4dc0371eba2d8c8b54794b0b0eb786a234a559b77593d6f80825b6d2c77a2" dependencies = [ "anchor-syn", - "anyhow", "proc-macro2 1.0.66", "quote 1.0.32", "syn 1.0.109", @@ -168,22 +162,20 @@ dependencies = [ [[package]] name = "anchor-attribute-program" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eebd21543606ab61e2d83d9da37d24d3886a49f390f9c43a1964735e8c0f0d5" +checksum = "b18c4f191331e078d4a6a080954d1576241c29c56638783322a18d308ab27e4f" dependencies = [ "anchor-syn", - "anyhow", - "proc-macro2 1.0.66", "quote 1.0.32", "syn 1.0.109", ] [[package]] name = "anchor-client" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8434a6bf33efba0c93157f7fa2fafac658cb26ab75396886dcedd87c2a8ad445" +checksum = "cb48c4a7911038da546dc752655a29fa49f6bd50ebc1edca218bac8da1012acd" dependencies = [ "anchor-lang", "anyhow", @@ -200,12 +192,23 @@ dependencies = [ [[package]] name = "anchor-derive-accounts" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec4720d899b3686396cced9508f23dab420f1308344456ec78ef76f98fda42af" +checksum = "5de10d6e9620d3bcea56c56151cad83c5992f50d5960b3a9bebc4a50390ddc3c" dependencies = [ "anchor-syn", - "anyhow", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-serde" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e2e5be518ec6053d90a2a7f26843dbee607583c779e6c8395951b9739bdfbe" +dependencies = [ + "anchor-syn", + "borsh-derive-internal 0.10.3", "proc-macro2 1.0.66", "quote 1.0.32", "syn 1.0.109", @@ -213,9 +216,9 @@ dependencies = [ [[package]] name = "anchor-derive-space" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f495e85480bd96ddeb77b71d499247c7d4e8b501e75ecb234e9ef7ae7bd6552a" +checksum = "1ecc31d19fa54840e74b7a979d44bcea49d70459de846088a1d71e87ba53c419" dependencies = [ "proc-macro2 1.0.66", "quote 1.0.32", @@ -224,9 +227,9 @@ dependencies = [ [[package]] name = "anchor-lang" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d2d4b20100f1310a774aba3471ef268e5c4ba4d5c28c0bbe663c2658acbc414" +checksum = "35da4785497388af0553586d55ebdc08054a8b1724720ef2749d313494f2b8ad" dependencies = [ "anchor-attribute-access-control", "anchor-attribute-account", @@ -235,6 +238,7 @@ dependencies = [ "anchor-attribute-event", "anchor-attribute-program", "anchor-derive-accounts", + "anchor-derive-serde", "anchor-derive-space", "arrayref", "base64 0.13.1", @@ -248,9 +252,9 @@ dependencies = [ [[package]] name = "anchor-spl" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78f860599da1c2354e7234c768783049eb42e2f54509ecfc942d2e0076a2da7b" +checksum = "6c4fd6e43b2ca6220d2ef1641539e678bfc31b6cc393cf892b373b5997b6a39a" dependencies = [ "anchor-lang", "solana-program", @@ -261,13 +265,13 @@ dependencies = [ [[package]] name = "anchor-syn" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a125e4b0cc046cfec58f5aa25038e34cf440151d58f0db3afc55308251fe936d" +checksum = "d9101b84702fed2ea57bd22992f75065da5648017135b844283a2f6d74f27825" dependencies = [ "anyhow", "bs58 0.5.0", - "heck 0.3.3", + "heck", "proc-macro2 1.0.66", "quote 1.0.32", "serde", @@ -575,9 +579,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" @@ -593,7 +597,7 @@ dependencies = [ "futures", "serde", "serde_json", - "switchboard-solana 0.28.20", + "switchboard-solana", "switchboard-utils", "tokio", ] @@ -603,7 +607,7 @@ name = "basic_oracle" version = "0.1.0" dependencies = [ "bytemuck", - "switchboard-solana 0.28.20 (registry+https://github.com/rust-lang/crates.io-index)", + "switchboard-solana", ] [[package]] @@ -853,9 +857,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" dependencies = [ "bytemuck_derive", ] @@ -967,7 +971,7 @@ dependencies = [ "atty", "bitflags 1.3.2", "clap_lex", - "indexmap 1.9.3", + "indexmap", "once_cell", "strsim 0.10.0", "termcolor", @@ -998,9 +1002,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" dependencies = [ "crossbeam-utils", ] @@ -1222,6 +1226,19 @@ dependencies = [ "syn 2.0.28", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.0", + "lock_api", + "once_cell", + "parking_lot_core 0.9.8", +] + [[package]] name = "data-encoding" version = "2.4.0" @@ -1340,6 +1357,12 @@ dependencies = [ "syn 0.15.44", ] +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + [[package]] name = "eager" version = "0.1.0" @@ -1445,10 +1468,13 @@ dependencies = [ ] [[package]] -name = "equivalent" -version = "1.0.1" +name = "erased-serde" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +dependencies = [ + "serde", +] [[package]] name = "errno" @@ -1489,12 +1515,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - [[package]] name = "flate2" version = "1.0.26" @@ -1700,7 +1720,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap", "slab", "tokio", "tokio-util", @@ -1758,12 +1778,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "hermit-abi" version = "0.1.19" @@ -1979,21 +1993,11 @@ dependencies = [ "hashbrown 0.12.3", ] -[[package]] -name = "indexmap" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" -dependencies = [ - "equivalent", - "hashbrown 0.14.0", -] - [[package]] name = "indicatif" -version = "0.17.6" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730" +checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" dependencies = [ "console", "instant", @@ -2086,6 +2090,15 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -2177,9 +2190,12 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +dependencies = [ + "value-bag", +] [[package]] name = "memchr" @@ -2269,12 +2285,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "multimap" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" - [[package]] name = "native-tls" version = "0.2.11" @@ -2295,16 +2305,15 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", "memoffset 0.7.1", "pin-utils", - "static_assertions", ] [[package]] @@ -2394,6 +2403,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "num-derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" +dependencies = [ + "proc-macro2 1.0.66", + "quote 1.0.32", + "syn 2.0.28", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -2448,41 +2468,41 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.11" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" dependencies = [ - "num_enum_derive 0.5.11", + "num_enum_derive 0.6.1", ] [[package]] name = "num_enum" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +checksum = "683751d591e6d81200c39fb0d1032608b77724f34114db54f571ff1317b337c0" dependencies = [ - "num_enum_derive 0.6.1", + "num_enum_derive 0.7.1", ] [[package]] name = "num_enum_derive" -version = "0.5.11" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 1.1.3", "proc-macro2 1.0.66", "quote 1.0.32", - "syn 1.0.109", + "syn 2.0.28", ] [[package]] name = "num_enum_derive" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 1.1.3", "proc-macro2 1.0.66", "quote 1.0.32", "syn 2.0.28", @@ -2705,16 +2725,6 @@ dependencies = [ "sha2 0.10.7", ] -[[package]] -name = "petgraph" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" -dependencies = [ - "fixedbitset", - "indexmap 1.9.3", -] - [[package]] name = "pin-project-lite" version = "0.2.12" @@ -2764,9 +2774,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.4.2" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f32154ba0af3a075eefa1eda8bb414ee928f62303a54ea85b8d6638ff1a6ee9e" +checksum = "3bccab0e7fd7cc19f820a1c8c91720af652d0c88dc9664dd72aef2614f04af3b" [[package]] name = "ppv-lite86" @@ -2774,16 +2784,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "prettyplease" -version = "0.1.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" -dependencies = [ - "proc-macro2 1.0.66", - "syn 1.0.109", -] - [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -2795,12 +2795,12 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" dependencies = [ - "once_cell", - "toml_edit", + "thiserror", + "toml", ] [[package]] @@ -2823,58 +2823,25 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.9" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +checksum = "f4fdd22f3b9c31b53c060df4a0613a1c7f062d4115a2b984dd15b1858f7e340d" dependencies = [ "bytes", "prost-derive", ] -[[package]] -name = "prost-build" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" -dependencies = [ - "bytes", - "heck 0.4.1", - "itertools", - "lazy_static", - "log", - "multimap", - "petgraph", - "prettyplease", - "prost", - "prost-types", - "pulldown-cmark", - "pulldown-cmark-to-cmark", - "regex", - "syn 1.0.109", - "tempfile", - "which", -] - [[package]] name = "prost-derive" -version = "0.11.9" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32" dependencies = [ "anyhow", "itertools", "proc-macro2 1.0.66", "quote 1.0.32", - "syn 1.0.109", -] - -[[package]] -name = "prost-types" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" -dependencies = [ - "prost", + "syn 2.0.28", ] [[package]] @@ -2897,26 +2864,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "pulldown-cmark" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" -dependencies = [ - "bitflags 1.3.2", - "memchr", - "unicase", -] - -[[package]] -name = "pulldown-cmark-to-cmark" -version = "10.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0194e6e1966c23cc5fd988714f85b18d548d773e81965413555d96569931833d" -dependencies = [ - "pulldown-cmark", -] - [[package]] name = "qstring" version = "0.7.2" @@ -2946,9 +2893,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.9.4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31999cfc7927c4e212e60fd50934ab40e8e8bfd2d493d6095d2d306bc0764d9" +checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863" dependencies = [ "bytes", "rand 0.8.5", @@ -3177,7 +3124,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91" dependencies = [ "async-compression", - "base64 0.21.2", + "base64 0.21.5", "bytes", "encoding_rs", "futures-core", @@ -3259,23 +3206,23 @@ dependencies = [ [[package]] name = "rpassword" -version = "7.2.0" +version = "7.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322" +checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" dependencies = [ "libc", "rtoolbox", - "winapi", + "windows-sys 0.48.0", ] [[package]] name = "rtoolbox" -version = "0.0.1" +version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034e22c514f5c0cb8a10ff341b9b048b5ceb21591f31c8f44c43b960f9b3524a" +checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e" dependencies = [ "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -3368,7 +3315,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.5", ] [[package]] @@ -3492,6 +3439,15 @@ dependencies = [ "syn 2.0.28", ] +[[package]] +name = "serde_fmt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" +dependencies = [ + "serde", +] + [[package]] name = "serde_json" version = "1.0.104" @@ -3667,12 +3623,12 @@ dependencies = [ [[package]] name = "solana-account-decoder" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298accbe9b2bffc391081b94f30ec3dd5bac053bfcd09aa78c06f1f87d33ec1e" +checksum = "5d8ea963f393c09376f21f7f5217d5701a18d65c821a68337188b6cf9c1255db" dependencies = [ "Inflector", - "base64 0.21.2", + "base64 0.21.5", "bincode", "bs58 0.4.0", "bv", @@ -3685,20 +3641,21 @@ dependencies = [ "solana-sdk", "spl-token", "spl-token-2022", + "spl-token-metadata-interface", "thiserror", "zstd", ] [[package]] name = "solana-address-lookup-table-program" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c026db45d6d8a21afe308fab93a40c77d21cb7a0f1f2fe4b99bb7bbcd7028ed7" +checksum = "5c284096b2d4595b13f61004142c6caff4f3dc40ba77dbd5f4071d67c256e15c" dependencies = [ "bincode", "bytemuck", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", "rustc_version", "serde", @@ -3712,9 +3669,9 @@ dependencies = [ [[package]] name = "solana-clap-utils" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d27f6ef67bb0519da2d7c7dd9f65c8e447a9a1c8330bb032b78d80712472fefd" +checksum = "b4371b20d9dff6a0e769cd103385e7c257d511efec11efd94c65ab52a39255e2" dependencies = [ "chrono", "clap 2.34.0", @@ -3730,15 +3687,15 @@ dependencies = [ [[package]] name = "solana-client" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13cf67b2f89d8ce5ce0b8c75baac79dc10b082cf096b149146724182db5506cf" +checksum = "78ee4db75f979886731e603f7bd22eeb3386cd1477a7592931e21623326da83b" dependencies = [ "async-trait", "bincode", "futures", "futures-util", - "indexmap 1.9.3", + "indexmap", "indicatif", "log", "quinn", @@ -3763,9 +3720,9 @@ dependencies = [ [[package]] name = "solana-config-program" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4065170279a38c1013fcf9c1776579914e7c30edb831f28dfd59f9d939d90f63" +checksum = "ae9df684ad70f3e3cb716a085652b545a64dfbc9299c59f768112ec69d4f4392" dependencies = [ "bincode", "chrono", @@ -3777,14 +3734,14 @@ dependencies = [ [[package]] name = "solana-connection-cache" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a98001f5293720075b52faa7e05c78c33ffdcc23ed7dea2cad102ed4823d624" +checksum = "c58c2e8007f2fd5ae0302ccaa7df72bdb6b1b40fd9f4b6c67f5e928dc58d9f35" dependencies = [ "async-trait", "bincode", "futures-util", - "indexmap 1.9.3", + "indexmap", "log", "rand 0.7.3", "rayon", @@ -3798,9 +3755,9 @@ dependencies = [ [[package]] name = "solana-frozen-abi" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee2b96d4150d9ebf55e903014bc332ac64c642837d7f1e6f7b911d709331380" +checksum = "9ab680d7d65fcecdea832cadb063fc3898121bc56cab15aee54f2c5db71af535" dependencies = [ "ahash 0.8.3", "blake3", @@ -3831,9 +3788,9 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942534eb972f955ed186175495654cabece6261a8ac3211e5791440d40a1ed96" +checksum = "b02411fefc004154edf3fe61cedb1dfb26ef82b659148b0a4b21ce3184d40ebc" dependencies = [ "proc-macro2 1.0.66", "quote 1.0.32", @@ -3843,9 +3800,9 @@ dependencies = [ [[package]] name = "solana-logger" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1339e1a179e2465e97fd89c2f70d5f00c5644f36c0e547b8ecda414c748dfc2c" +checksum = "f9c7f0c4504c512f93aed16fb07449cafa5fa0c54ef7cfff6f377b2a5ed34553" dependencies = [ "env_logger", "lazy_static", @@ -3854,9 +3811,9 @@ dependencies = [ [[package]] name = "solana-measure" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b3feab384868634ea5d7a12fc62c001d5785b6a352b7903ad13edbb7d3043f3" +checksum = "ceb54a32ad5125ed514c058639ac86508efcffc2412f713e3140eb70291d9843" dependencies = [ "log", "solana-sdk", @@ -3864,9 +3821,9 @@ dependencies = [ [[package]] name = "solana-metrics" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31c1f2569ea75ee9aa73eedb948b17eabc468e6cd5c1aee4d9cdfaffb0f3d33" +checksum = "ef674e1c16731541af6f58515ebdae519f68d374a3018675dc9ee3480b4a640e" dependencies = [ "crossbeam-channel", "gethostname", @@ -3878,9 +3835,9 @@ dependencies = [ [[package]] name = "solana-net-utils" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "725a2f7335cc7ec5be356baaf44b0d3211f996b174e2a3b340227e700d26fc55" +checksum = "a39ab5b49d50c50411fe1990b097458dd3d23aee1753db9b13f69a2f946409f5" dependencies = [ "bincode", "clap 3.2.25", @@ -3900,9 +3857,9 @@ dependencies = [ [[package]] name = "solana-perf" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2048b4890677ec4287a205a0f53d6a9bf2bdbcc7046aeb665b2714e3c1a4e655" +checksum = "710431ce6bc8a070c3b54999f9602b8b4c94358836615e89e357114ea0ae1fe5" dependencies = [ "ahash 0.8.3", "bincode", @@ -3927,16 +3884,16 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f81c59ed0b65b403cc5db459dd1214dfab89ccd3ce20aadf98102b072d08562" +checksum = "aedf18ad0e74ce21123eb94c45d8b469d280a6a3e4f1bf6411fc4ca8fc7c2eac" dependencies = [ "ark-bn254", "ark-ec", "ark-ff", "ark-serialize", "array-bytes", - "base64 0.21.2", + "base64 0.21.5", "bincode", "bitflags 1.3.2", "blake3", @@ -3958,7 +3915,7 @@ dependencies = [ "log", "memoffset 0.9.0", "num-bigint 0.4.3", - "num-derive", + "num-derive 0.3.3", "num-traits", "parking_lot 0.12.1", "rand 0.7.3", @@ -3982,18 +3939,18 @@ dependencies = [ [[package]] name = "solana-program-runtime" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc8624325d63e9a643385739c53315d8768aff689dfa9ad06ed1c67aac163ab2" +checksum = "d9e3ff03078645ddd91e2a3eb2d58a90a5a6c9d7e8c2b9c2b3511f24ea03b711" dependencies = [ - "base64 0.21.2", + "base64 0.21.5", "bincode", "eager", "enum-iterator", "itertools", "libc", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", "percentage", "rand 0.7.3", @@ -4010,9 +3967,9 @@ dependencies = [ [[package]] name = "solana-pubsub-client" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e10c8caee33c14b74fa2e76f8d8638364303bbf4439e284fddf66b7e3a5acb" +checksum = "8c7d115473531dbc447989e3e6eb24a418bf3c0b7ffb86da17c4a1271d1ce553" dependencies = [ "crossbeam-channel", "futures-util", @@ -4035,9 +3992,9 @@ dependencies = [ [[package]] name = "solana-quic-client" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7173c8eb7b20a1c04838655760ba36e5a4398dc9cd16115a5321c7a56e6a34ff" +checksum = "bca1af43f5b44321e2a5f48798d07ade968c7d95c3191ef2f8e167a481ed4d37" dependencies = [ "async-mutex", "async-trait", @@ -4063,9 +4020,9 @@ dependencies = [ [[package]] name = "solana-rayon-threadlimit" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe5195e62d9457233f97f30aa678f71b1aaed2200a170e63f0da7d9a3d124aa3" +checksum = "cb5a290bb5b316654d165326c1ed22cf15a40559523824097308913cce2dcad7" dependencies = [ "lazy_static", "num_cpus", @@ -4073,14 +4030,14 @@ dependencies = [ [[package]] name = "solana-remote-wallet" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04b5777335473d24b6edf9ca36129b1f8e07ba34de18e2b8d6285a4e3473260c" +checksum = "a082793597a5467271d35cbee5e3782e42a0b52849521f293b6bc07f9514d018" dependencies = [ "console", "dialoguer", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", "parking_lot 0.12.1", "qstring", @@ -4092,12 +4049,12 @@ dependencies = [ [[package]] name = "solana-rpc-client" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d34afb705efdf62ad1a911beffe3c6d599eab2125bd07460e85a424636cb54" +checksum = "b6ed31f6dd0546a92daf7493c94b602e6c06e59b474d5a81559ff88d6d3e8afa" dependencies = [ "async-trait", - "base64 0.21.2", + "base64 0.21.5", "bincode", "bs58 0.4.0", "indicatif", @@ -4118,11 +4075,11 @@ dependencies = [ [[package]] name = "solana-rpc-client-api" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e28db9b3748bfe7367ef9e9b968be1643f63ab9c360e89681d426d036cf69a" +checksum = "e846fb99c6aa3d044cb556f40156a585dd3f4cb1e416b5b8319028d3f731b6a8" dependencies = [ - "base64 0.21.2", + "base64 0.21.5", "bs58 0.4.0", "jsonrpc-core", "reqwest", @@ -4140,9 +4097,9 @@ dependencies = [ [[package]] name = "solana-rpc-client-nonce-utils" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27c9c9f034bf3c931441a0fbb528b8e3bf417a32b70546e5fa0c00cd78559ff5" +checksum = "cc5ac3f71c723bf061e684c1bcf9be29b99d07fd6be54cf9e12f1cc1629d4f74" dependencies = [ "clap 2.34.0", "solana-clap-utils", @@ -4153,12 +4110,12 @@ dependencies = [ [[package]] name = "solana-sdk" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23dbf6da55a2d191956c693d8490dc809799822536aceb11309043e9b622079" +checksum = "d6aea1e7067980ca1ef57a31c498413547b82aa392d9e7ec5539968f1a8dec1c" dependencies = [ "assert_matches", - "base64 0.21.2", + "base64 0.21.5", "bincode", "bitflags 1.3.2", "borsh 0.10.3", @@ -4178,7 +4135,7 @@ dependencies = [ "libsecp256k1", "log", "memmap2", - "num-derive", + "num-derive 0.3.3", "num-traits", "num_enum 0.6.1", "pbkdf2 0.11.0", @@ -4206,9 +4163,9 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7d686e405694cd6510cd77bb87d0eeda64ad3df08d3293278ba47ca78b8e5e" +checksum = "dbca599523925e4c55e0326d93eef0a8e1918df5f93897811abf3f5972e21bec" dependencies = [ "bs58 0.4.0", "proc-macro2 1.0.66", @@ -4219,16 +4176,16 @@ dependencies = [ [[package]] name = "solana-streamer" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e40e74d6ae01dd21dc1a93a2213f8d7e04aea69079092a131ad5bd2d54aa16bc" +checksum = "2147a8042ec522d31a5ec67ef06000d7c4d528d7ce49a2e5225687fb5ad08ea8" dependencies = [ "async-channel", "bytes", "crossbeam-channel", "futures-util", "histogram", - "indexmap 1.9.3", + "indexmap", "itertools", "libc", "log", @@ -4252,9 +4209,9 @@ dependencies = [ [[package]] name = "solana-thin-client" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f3a1dae21f002f2d35ddfcc09fb528bc52936bb9fe4aea7bb46b1361998ed7" +checksum = "8af1069859646695b53b88cf071ba3c2ce49f0fbe9b19014440676e1869704f5" dependencies = [ "bincode", "log", @@ -4267,14 +4224,14 @@ dependencies = [ [[package]] name = "solana-tpu-client" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fffd371a68959dbbbb073198cd93121586da924a8dc493bd624a5ddf40a6742" +checksum = "d9bc57c809b5ee98570bd0981c3ecce339d4053f8473ab2d57a9487ad3aea5af" dependencies = [ "async-trait", "bincode", "futures-util", - "indexmap 1.9.3", + "indexmap", "indicatif", "log", "rand 0.7.3", @@ -4292,14 +4249,14 @@ dependencies = [ [[package]] name = "solana-transaction-status" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeb3b1a35fc4718e758851670a959bb4736a8825f56c7ebfcd6eec892cbd200a" +checksum = "f225ca544e1005918608bfe67f97c1cfdfe43bb6ab41e0bd77491258a7e5e8f8" dependencies = [ "Inflector", - "base64 0.21.2", + "base64 0.21.5", "bincode", - "borsh 0.9.3", + "borsh 0.10.3", "bs58 0.4.0", "lazy_static", "log", @@ -4318,9 +4275,9 @@ dependencies = [ [[package]] name = "solana-udp-client" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05fd1c52102c716767d32a6936843b0505ad61bad958b34bcff513fe609611e7" +checksum = "be1dbf725b5e31863f34553c1333e8d8e098c6259bbed433630022aa59e9a175" dependencies = [ "async-trait", "solana-connection-cache", @@ -4333,9 +4290,9 @@ dependencies = [ [[package]] name = "solana-version" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4f9750ce47f0a431338121a3247bd29665d6da5a8ebde8c5320503c98d8adc" +checksum = "cc8ac5da4f0044a857cb35bf0a146e76400541fce72f0638b9377fd368cf2da0" dependencies = [ "log", "rustc_version", @@ -4349,13 +4306,13 @@ dependencies = [ [[package]] name = "solana-vote-program" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258b4c3e62faaed0cd864b02760659e45fb4431a287ee0088ae79af891ae4786" +checksum = "ee3c171647345a050eaf80846d99f888c55c2bcbdd0297dfae38597950ca6054" dependencies = [ "bincode", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", "rustc_version", "serde", @@ -4371,12 +4328,12 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" -version = "1.16.7" +version = "1.16.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2d04eecf3a7438c95db28b57437e94f09a1e60377183d9bea0c9db84506f504" +checksum = "b8d5a0aa72c38c45b134e6fc008569fe1b0882c7cff5fceb7e42c0406925d3e5" dependencies = [ "aes-gcm-siv", - "base64 0.21.2", + "base64 0.21.5", "bincode", "bytemuck", "byteorder", @@ -4385,7 +4342,7 @@ dependencies = [ "itertools", "lazy_static", "merlin", - "num-derive", + "num-derive 0.3.3", "num-traits", "rand 0.7.3", "serde", @@ -4400,9 +4357,9 @@ dependencies = [ [[package]] name = "solana_rbpf" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3082ec3a1d4ef7879eb5b84916d5acde057abd59733eec3647e0ab8885283ef" +checksum = "17d4ba1e58947346e360fabde0697029d36ba83c42f669199b16a8931313cf29" dependencies = [ "byteorder", "combine", @@ -4435,13 +4392,13 @@ dependencies = [ [[package]] name = "spl-associated-token-account" -version = "1.1.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978dba3bcbe88d0c2c58366c254d9ea41c5f73357e72fc0bdee4d6b5fc99c8f4" +checksum = "385e31c29981488f2820b2022d8e731aae3b02e6e18e2fd854e4c9a94dc44fc3" dependencies = [ "assert_matches", - "borsh 0.9.3", - "num-derive", + "borsh 0.10.3", + "num-derive 0.4.1", "num-traits", "solana-program", "spl-token", @@ -4449,48 +4406,182 @@ dependencies = [ "thiserror", ] +[[package]] +name = "spl-discriminator" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cce5d563b58ef1bb2cdbbfe0dfb9ffdc24903b10ae6a4df2d8f425ece375033f" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator-derive", +] + +[[package]] +name = "spl-discriminator-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fadbefec4f3c678215ca72bd71862697bb06b41fd77c0088902dd3203354387b" +dependencies = [ + "quote 1.0.32", + "spl-discriminator-syn", + "syn 2.0.28", +] + +[[package]] +name = "spl-discriminator-syn" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e5f2044ca42c8938d54d1255ce599c79a1ffd86b677dfab695caa20f9ffc3f2" +dependencies = [ + "proc-macro2 1.0.66", + "quote 1.0.32", + "sha2 0.10.7", + "syn 2.0.28", + "thiserror", +] + [[package]] name = "spl-memo" -version = "3.0.1" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0dc6f70db6bacea7ff25870b016a65ba1d1b6013536f08e4fd79a8f9005325" +checksum = "f0f180b03318c3dbab3ef4e1e4d46d5211ae3c780940dd0a28695aba4b59a75a" dependencies = [ "solana-program", ] +[[package]] +name = "spl-pod" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2881dddfca792737c0706fa0175345ab282b1b0879c7d877bad129645737c079" +dependencies = [ + "borsh 0.10.3", + "bytemuck", + "solana-program", + "solana-zk-token-sdk", + "spl-program-error", +] + +[[package]] +name = "spl-program-error" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "249e0318493b6bcf27ae9902600566c689b7dfba9f1bdff5893e92253374e78c" +dependencies = [ + "num-derive 0.4.1", + "num-traits", + "solana-program", + "spl-program-error-derive", + "thiserror", +] + +[[package]] +name = "spl-program-error-derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5269c8e868da17b6552ef35a51355a017bd8e0eae269c201fef830d35fa52c" +dependencies = [ + "proc-macro2 1.0.66", + "quote 1.0.32", + "sha2 0.10.7", + "syn 2.0.28", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062e148d3eab7b165582757453632ffeef490c02c86a48bfdb4988f63eefb3b9" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + [[package]] name = "spl-token" -version = "3.5.0" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e85e168a785e82564160dcb87b2a8e04cee9bfd1f4d488c729d53d6a4bd300d" +checksum = "08459ba1b8f7c1020b4582c4edf0f5c7511a5e099a7a97570c9698d4f2337060" dependencies = [ "arrayref", "bytemuck", - "num-derive", + "num-derive 0.3.3", "num-traits", - "num_enum 0.5.11", + "num_enum 0.6.1", "solana-program", "thiserror", ] [[package]] name = "spl-token-2022" -version = "0.6.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0043b590232c400bad5ee9eb983ced003d15163c4c5d56b090ac6d9a57457b47" +checksum = "e4abf34a65ba420584a0c35f3903f8d727d1f13ababbdc3f714c6b065a686e86" dependencies = [ "arrayref", "bytemuck", - "num-derive", + "num-derive 0.4.1", "num-traits", - "num_enum 0.5.11", + "num_enum 0.7.1", "solana-program", "solana-zk-token-sdk", "spl-memo", + "spl-pod", "spl-token", + "spl-token-metadata-interface", + "spl-transfer-hook-interface", + "spl-type-length-value", "thiserror", ] +[[package]] +name = "spl-token-metadata-interface" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" +dependencies = [ + "borsh 0.10.3", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051d31803f873cabe71aec3c1b849f35248beae5d19a347d93a5c9cccc5d5a9b" +dependencies = [ + "arrayref", + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value", +] + +[[package]] +name = "spl-type-length-value" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a468e6f6371f9c69aae760186ea9f1a01c2908351b06a5e0026d21cfc4d7ecac" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -4521,87 +4612,157 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" +[[package]] +name = "sval" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15df12a8db7c216a04b4b438f90d50d5335cd38f161b56389c9f5c9d96d0873" + +[[package]] +name = "sval_buffer" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e80556bc8acea0446e574ce542ad6114a76a0237f28a842bc01ca3ea98f479" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d93d2259edb1d7b4316179f0a98c62e3ffc726f47ab200e07cfe382771f57b8" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532f7f882226f7a5a4656f5151224aaebf8217e0d539cb1595b831bace921343" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e03bd8aa0ae6ee018f7ae95c9714577687a4415bd1a5f19b26e34695f7e072" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_ref" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75ed054f2fb8c2a0ab5d36c1ec57b412919700099fc5e32ad8e7a38b23e1a9e1" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff191c4ff05b67e3844c161021427646cde5d6624597958be158357d9200586" +dependencies = [ + "serde", + "sval", + "sval_buffer", + "sval_fmt", +] + [[package]] name = "switchboard-common" -version = "0.8.18" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c9e28848b864786d8b1835f1f0c4c7e65190d9c17b246e5e21cc2457a70b176" +checksum = "ea14d8fd81943403ad32221a234b41cab6faf740c9e62069e672af53079cacc5" dependencies = [ "envy", "getrandom 0.2.10", "hex", + "log", "serde", "serde_json", "sgx-quote", "sha2 0.10.7", + "sha3 0.9.1", ] [[package]] name = "switchboard-common" -version = "0.8.19" +version = "0.11.0" dependencies = [ + "async-trait", + "base64 0.21.5", "envy", + "futures", "getrandom 0.2.10", "hex", + "log", "serde", "serde_json", "sgx-quote", "sha2 0.10.7", + "sha3 0.10.8", ] [[package]] name = "switchboard-solana" -version = "0.28.20" +version = "0.29.70" dependencies = [ "anchor-client", "anchor-lang", "anchor-spl", + "base64 0.21.5", "bincode", "bytemuck", "chrono", "cron", + "dashmap", + "futures", "hex", + "kv-log-macro", + "log", "rust_decimal", + "serde", + "serde_json", "sgx-quote", + "sha2 0.10.7", + "solana-account-decoder", "solana-address-lookup-table-program", "solana-client", "solana-program", "superslice", - "switchboard-common 0.8.19", + "switchboard-common 0.11.0", + "switchboard-solana-macros", "tokio", "url", ] [[package]] -name = "switchboard-solana" -version = "0.28.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a978513e0d3f54444698efb1737c8bcf366e2131e03ccfdf24c22210b8d755c" +name = "switchboard-solana-macros" +version = "0.2.1" dependencies = [ - "anchor-client", - "anchor-lang", - "anchor-spl", - "bincode", - "bytemuck", - "chrono", - "cron", - "hex", - "rust_decimal", - "sgx-quote", - "solana-address-lookup-table-program", - "solana-client", - "solana-program", - "superslice", - "switchboard-common 0.8.18", - "tokio", - "url", + "dotenvy", + "proc-macro2 1.0.66", + "quote 1.0.32", + "syn 2.0.28", ] [[package]] name = "switchboard-utils" -version = "0.8.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e18a6e7377b936fbd485fa641e6c2c7ad37e03336da90ef554c81df25369ecac" +checksum = "c88063525c992a9756e940ac18cee33b7c7a560ecb45f3c35dcacac8d86fb6cf" dependencies = [ "bytes", "bytestring", @@ -4609,12 +4770,11 @@ dependencies = [ "futures-util", "jsonpath-rust", "prost", - "prost-build", "reqwest", "serde", "serde_derive", "serde_json", - "switchboard-common 0.8.18", + "switchboard-common 0.9.5", "tokio", "url", ] @@ -4902,23 +5062,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_datetime" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" - -[[package]] -name = "toml_edit" -version = "0.19.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" -dependencies = [ - "indexmap 2.0.0", - "toml_datetime", - "winnow", -] - [[package]] name = "tower-service" version = "0.3.2" @@ -4997,15 +5140,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-bidi" version = "0.3.13" @@ -5109,6 +5243,42 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +[[package]] +name = "value-bag" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a72e1902dde2bd6441347de2b70b7f5d59bf157c6c62f0c44572607a1d55bbe" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ba39dc791ecb35baad371a3fc04c6eab688c04937d2e0ac6c22b612c0357bf" +dependencies = [ + "erased-serde", + "serde", + "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e06c10810a57bbf45778d023d432a50a1daa7d185991ae06bcfb6c654d0945" +dependencies = [ + "sval", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", +] + [[package]] name = "vcpkg" version = "0.2.15" @@ -5255,17 +5425,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "which" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" -dependencies = [ - "either", - "libc", - "once_cell", -] - [[package]] name = "winapi" version = "0.3.9" @@ -5453,15 +5612,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" -[[package]] -name = "winnow" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acaaa1190073b2b101e15083c38ee8ec891b5e05cbee516521e94ec008f61e64" -dependencies = [ - "memchr", -] - [[package]] name = "winreg" version = "0.10.1" diff --git a/examples/functions/01_basic_oracle/switchboard-function/Cargo.toml b/examples/functions/01_basic_oracle/switchboard-function/Cargo.toml index 6228abe9e..0ba0db0e8 100644 --- a/examples/functions/01_basic_oracle/switchboard-function/Cargo.toml +++ b/examples/functions/01_basic_oracle/switchboard-function/Cargo.toml @@ -15,7 +15,9 @@ tokio = "^1" futures = "0.3" serde = "^1" serde_json = "^1" -switchboard-utils = "0.8.0" -# switchboard-solana = { version = "0.28.19" } -switchboard-solana = { version = "0.28.19", path = "../../../../rust/switchboard-solana" } -# switchboard-utils = { version = "0.8.0", path = "../../../../../../rust/switchboard-utils" } +switchboard-utils = "0.8.5" +# switchboard-solana = { version = "0.28.43" } +switchboard-solana = { path = "../../../../rust/switchboard-solana", features = [ + "macros", +] } +# switchboard-utils = { path = "../../../../../../rust/switchboard-utils" } diff --git a/examples/functions/01_basic_oracle/switchboard-function/Dockerfile.dev b/examples/functions/01_basic_oracle/switchboard-function/Dockerfile.dev index 11d49e3bf..ae4b44268 100644 --- a/examples/functions/01_basic_oracle/switchboard-function/Dockerfile.dev +++ b/examples/functions/01_basic_oracle/switchboard-function/Dockerfile.dev @@ -7,6 +7,10 @@ COPY ./rust/switchboard-common/Cargo.toml \ ./rust/switchboard-common/Cargo.lock \ ./rust/switchboard-common/ +COPY ./rust/switchboard-utils/Cargo.toml \ + ./rust/switchboard-utils/Cargo.lock \ + ./rust/switchboard-utils/ + COPY ./rust/switchboard-solana/Cargo.toml \ ./rust/switchboard-solana/Cargo.lock \ ./rust/switchboard-solana/ @@ -22,6 +26,9 @@ COPY ./chains/solana/examples/functions/01_basic_oracle/switchboard-function/Car COPY ./rust/switchboard-common/src \ ./rust/switchboard-common/src/ +COPY ./rust/switchboard-utils/src \ + ./rust/switchboard-utils/src/ + COPY ./rust/switchboard-solana/src \ ./rust/switchboard-solana/src/ diff --git a/examples/functions/01_basic_oracle/switchboard-function/Makefile b/examples/functions/01_basic_oracle/switchboard-function/Makefile index f23cc6f0c..b02170846 100644 --- a/examples/functions/01_basic_oracle/switchboard-function/Makefile +++ b/examples/functions/01_basic_oracle/switchboard-function/Makefile @@ -1,7 +1,7 @@ .PHONY: build clean publish # Variables -DOCKER_IMAGE_NAME ?= gallynaut/basic-oracle-function +DOCKER_IMAGE_NAME ?= gallynaut/basic-oracle-function-v1 DOCKER_BUILD_COMMAND=docker buildx build --platform linux/amd64 diff --git a/examples/functions/01_basic_oracle/switchboard-function/src/binance.rs b/examples/functions/01_basic_oracle/switchboard-function/src/binance.rs index b8a066d84..0c5ce3132 100644 --- a/examples/functions/01_basic_oracle/switchboard-function/src/binance.rs +++ b/examples/functions/01_basic_oracle/switchboard-function/src/binance.rs @@ -79,7 +79,7 @@ pub struct Binance { impl Binance { // Fetch data from the Binance API - pub async fn fetch() -> std::result::Result { + pub async fn fetch() -> std::result::Result { let symbols = ["BTCUSDT", "USDCUSDT", "ETHUSDT", "SOLUSDT", "DOGEUSDT"]; let tickers_1hr = reqwest::get(format!( @@ -151,20 +151,19 @@ impl Binance { OracleDataWithTradingSymbol { symbol: TradingSymbol::Eth, data: self.eth_usdt.clone().into(), - }, - // OracleDataWithTradingSymbol { - // symbol: TradingSymbol::Sol, - // data: self.sol_usdt.clone().into(), - // }, - // OracleDataWithTradingSymbol { - // symbol: TradingSymbol::Doge, - // data: self.doge_usdt.clone().into(), - // }, + }, // OracleDataWithTradingSymbol { + // symbol: TradingSymbol::Sol, + // data: self.sol_usdt.clone().into(), + // }, + // OracleDataWithTradingSymbol { + // symbol: TradingSymbol::Doge, + // data: self.doge_usdt.clone().into(), + // }, ]; let params = RefreshPricesParams { rows }; - let (program_state_pubkey, _state_bump) = + let (_program_state_pubkey, _state_bump) = Pubkey::find_program_address(&[b"BASICORACLE"], &PROGRAM_ID); let (oracle_pubkey, _oracle_bump) = @@ -183,6 +182,11 @@ impl Binance { is_signer: false, is_writable: false, }, + AccountMeta { + pubkey: runner.function_routine_key.unwrap(), + is_signer: false, + is_writable: false, + }, AccountMeta { pubkey: runner.signer, is_signer: true, diff --git a/examples/functions/01_basic_oracle/switchboard-function/src/main.rs b/examples/functions/01_basic_oracle/switchboard-function/src/main.rs index f2bd0a671..b55703e01 100644 --- a/examples/functions/01_basic_oracle/switchboard-function/src/main.rs +++ b/examples/functions/01_basic_oracle/switchboard-function/src/main.rs @@ -1,17 +1,18 @@ -pub use switchboard_solana::prelude::*; +pub use switchboard_solana::switchboard_function; pub mod binance; pub use binance::*; -type Result = std::result::Result>; - pub use basic_oracle::{ self, OracleData, OracleDataWithTradingSymbol, RefreshPrices, RefreshPricesParams, SwitchboardDecimal, TradingSymbol, ID as PROGRAM_ID, }; -pub async fn perform(runner: &FunctionRunner) -> Result<()> { - +#[switchboard_function] +pub async fn binance_oracle_function( + runner: FunctionRunner, + _params: Vec, +) -> Result, SbFunctionError> { msg!("function runner loaded!"); // Then, write your own Rust logic and build a Vec of instructions. @@ -19,25 +20,6 @@ pub async fn perform(runner: &FunctionRunner) -> Result<()> { let binance = Binance::fetch().await?; let ixs: Vec = binance.to_ixns(&runner); - msg!("sending transaction"); - - // Finally, emit the signed quote and partially signed transaction to the functionRunner oracle - // The functionRunner oracle will use the last outputted word to stdout as the serialized result. This is what gets executed on-chain. - runner.emit(ixs).await?; - Ok(()) -} - -#[tokio::main(worker_threads = 12)] -async fn main() -> Result<()> { - // First, initialize the runner instance with a freshly generated Gramine keypair - let runner = FunctionRunner::from_env(None)?; - if runner.assert_mr_enclave().is_err() { - runner.emit_error(199).await?; - } - - let res = perform(&runner).await; - if let Some(e) = res.err() { - runner.emit_error(1).await?; - } - Ok(()) + // Emit the instructions for the oracle to validate and relay on-chain + Ok(ixs) } diff --git a/examples/functions/01_basic_oracle/tests/basic_oracle.ts b/examples/functions/01_basic_oracle/tests/basic_oracle.ts index d5664fdad..0ca406032 100644 --- a/examples/functions/01_basic_oracle/tests/basic_oracle.ts +++ b/examples/functions/01_basic_oracle/tests/basic_oracle.ts @@ -79,7 +79,6 @@ describe("basic_oracle", () => { { name: "test function", metadata: "this function handles XYZ for my protocol", - schedule: "15 * * * * *", container: "switchboardlabs/basic-oracle-function", version: "latest", mrEnclave: MRENCLAVE, diff --git a/examples/functions/02_liquidity_oracle/package.json b/examples/functions/02_liquidity_oracle/package.json index 432f131ff..b35de86cb 100644 --- a/examples/functions/02_liquidity_oracle/package.json +++ b/examples/functions/02_liquidity_oracle/package.json @@ -14,8 +14,8 @@ "@coral-xyz/anchor": "^0.28.0", "@solana/spl-token": "^0.3.8", "@solana/web3.js": "^1.78.3", - "@switchboard-xyz/common": "^2.3.3", - "@switchboard-xyz/solana.js": "^2.5.0" + "@switchboard-xyz/common": "*", + "@switchboard-xyz/solana.js": "*" }, "devDependencies": { "@types/bn.js": "^5.1.0", diff --git a/examples/functions/03_candles_oracle/package.json b/examples/functions/03_candles_oracle/package.json index 71cf2f4f1..4f9b370e2 100644 --- a/examples/functions/03_candles_oracle/package.json +++ b/examples/functions/03_candles_oracle/package.json @@ -15,8 +15,8 @@ "@coral-xyz/anchor": "^0.28.0", "@solana/spl-token": "^0.3.8", "@solana/web3.js": "^1.78.3", - "@switchboard-xyz/common": "^2.3.3", - "@switchboard-xyz/solana.js": "^2.5.0" + "@switchboard-xyz/common": "*", + "@switchboard-xyz/solana.js": "*" }, "devDependencies": { "@types/bn.js": "^5.1.0", diff --git a/examples/functions/04_randomness_callback/Cargo.toml b/examples/functions/04_randomness_callback/Cargo.toml index 0c5973d01..8821d9e04 100644 --- a/examples/functions/04_randomness_callback/Cargo.toml +++ b/examples/functions/04_randomness_callback/Cargo.toml @@ -20,5 +20,5 @@ default = [] [dependencies] bytemuck = "^1" anchor-spl = "0.28.0" -switchboard-solana = "0.28.19" -# switchboard-solana = { version = "0.28.19", path = "../../../rust/switchboard-solana" } +switchboard-solana = "0.28.43" +# switchboard-solana = { path = "../../../rust/switchboard-solana" } diff --git a/examples/functions/04_randomness_callback/package.json b/examples/functions/04_randomness_callback/package.json index 39422e6f8..2329dbbff 100644 --- a/examples/functions/04_randomness_callback/package.json +++ b/examples/functions/04_randomness_callback/package.json @@ -10,8 +10,8 @@ "@coral-xyz/anchor": "^0.28.0", "@solana/spl-token": "^0.3.8", "@solana/web3.js": "^1.78.4", - "@switchboard-xyz/common": "^2.3.3", - "@switchboard-xyz/solana.js": "^2.5.0", + "@switchboard-xyz/common": "*", + "@switchboard-xyz/solana.js": "*", "dotenv": "^16.3.1" }, "devDependencies": { diff --git a/examples/functions/04_randomness_callback/switchboard-function/Cargo.lock b/examples/functions/04_randomness_callback/switchboard-function/Cargo.lock index f7e26fec7..b6a8be752 100644 --- a/examples/functions/04_randomness_callback/switchboard-function/Cargo.lock +++ b/examples/functions/04_randomness_callback/switchboard-function/Cargo.lock @@ -34,7 +34,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" dependencies = [ "cfg-if", - "cipher", + "cipher 0.3.0", "cpufeatures", "opaque-debug", ] @@ -47,7 +47,7 @@ checksum = "589c637f0e68c877bbd59a4599bbe849cac8e5f3e4b5a3ebae8f528cd218dcdc" dependencies = [ "aead", "aes", - "cipher", + "cipher 0.3.0", "ctr", "polyval", "subtle", @@ -72,7 +72,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if", - "getrandom 0.2.10", "once_cell", "version_check", ] @@ -103,9 +102,9 @@ dependencies = [ [[package]] name = "anchor-attribute-access-control" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa5be5b72abea167f87c868379ba3c2be356bfca9e6f474fd055fa0f7eeb4f2" +checksum = "2d5e1a413b311b039d29b61d0dbb401c9dbf04f792497ceca87593454bf6d7dd" dependencies = [ "anchor-syn", "anyhow", @@ -117,13 +116,13 @@ dependencies = [ [[package]] name = "anchor-attribute-account" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f468970344c7c9f9d03b4da854fd7c54f21305059f53789d0045c1dd803f0018" +checksum = "cca9aeaf633c6e2365fed0525dcac68610be58eee5dc69d3b86fe0b1d4b320b9" dependencies = [ "anchor-syn", "anyhow", - "bs58 0.5.0", + "bs58 0.4.0", "proc-macro2 1.0.64", "quote 1.0.29", "rustversion", @@ -132,9 +131,9 @@ dependencies = [ [[package]] name = "anchor-attribute-constant" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59948e7f9ef8144c2aefb3f32a40c5fce2798baeec765ba038389e82301017ef" +checksum = "788e44f9e8501dabeb6f9229da0f3268fb2ae3208912608ffaa056a72031296f" dependencies = [ "anchor-syn", "proc-macro2 1.0.64", @@ -143,9 +142,9 @@ dependencies = [ [[package]] name = "anchor-attribute-error" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc753c9d1c7981cb8948cf7e162fb0f64558999c0413058e2d43df1df5448086" +checksum = "ea0c4d8c7e4a2605ede6fcdced9690288b2f74e24768619a85229d57e597bc97" dependencies = [ "anchor-syn", "proc-macro2 1.0.64", @@ -155,9 +154,9 @@ dependencies = [ [[package]] name = "anchor-attribute-event" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38b4e172ba1b52078f53fdc9f11e3dc0668ad27997838a0aad2d148afac8c97" +checksum = "7a3b07d5c5d87b5edc72428b447b8e9ee1143b83dd1afc6a6b1d352c6a6164d8" dependencies = [ "anchor-syn", "anyhow", @@ -168,9 +167,9 @@ dependencies = [ [[package]] name = "anchor-attribute-program" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eebd21543606ab61e2d83d9da37d24d3886a49f390f9c43a1964735e8c0f0d5" +checksum = "b22ad0445115dbea5869b1d062da49ae125abed9132fc20c33227f25e42dfa6b" dependencies = [ "anchor-syn", "anyhow", @@ -181,28 +180,26 @@ dependencies = [ [[package]] name = "anchor-client" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8434a6bf33efba0c93157f7fa2fafac658cb26ab75396886dcedd87c2a8ad445" +checksum = "04c06e06497b5b4f392845e0d04dde8374fd244fa2832dd0e5c27bfd99cb0342" dependencies = [ "anchor-lang", "anyhow", - "futures", "regex", "serde", "solana-account-decoder", "solana-client", "solana-sdk", "thiserror", - "tokio", "url", ] [[package]] name = "anchor-derive-accounts" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec4720d899b3686396cced9508f23dab420f1308344456ec78ef76f98fda42af" +checksum = "48daeff6781ba2f02961b0ad211feb9a2de75af345d42c62b1a252fd4dfb0724" dependencies = [ "anchor-syn", "anyhow", @@ -213,9 +210,9 @@ dependencies = [ [[package]] name = "anchor-derive-space" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f495e85480bd96ddeb77b71d499247c7d4e8b501e75ecb234e9ef7ae7bd6552a" +checksum = "c4fe2886f92c4f33ec1b2b8b2b43ca1b9070cf4929e63c7eaaa09a9f2c0d5123" dependencies = [ "proc-macro2 1.0.64", "quote 1.0.29", @@ -224,9 +221,9 @@ dependencies = [ [[package]] name = "anchor-lang" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d2d4b20100f1310a774aba3471ef268e5c4ba4d5c28c0bbe663c2658acbc414" +checksum = "dbbe5d1c7c057c6d63b4f2f538a320e4a22111126c9966340c3d9490e2f15ed1" dependencies = [ "anchor-attribute-access-control", "anchor-attribute-account", @@ -239,18 +236,17 @@ dependencies = [ "arrayref", "base64 0.13.1", "bincode", - "borsh 0.10.3", + "borsh 0.9.3", "bytemuck", - "getrandom 0.2.10", "solana-program", "thiserror", ] [[package]] name = "anchor-spl" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78f860599da1c2354e7234c768783049eb42e2f54509ecfc942d2e0076a2da7b" +checksum = "75cc8066fbd45e0e03edf48342c79265aa34ca76cefeace48ef6c402b6946665" dependencies = [ "anchor-lang", "solana-program", @@ -261,18 +257,18 @@ dependencies = [ [[package]] name = "anchor-syn" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a125e4b0cc046cfec58f5aa25038e34cf440151d58f0db3afc55308251fe936d" +checksum = "11cb31fe143aedb36fc41409ea072aa0b840cbea727e62eb2ff6e7b6cea036ff" dependencies = [ "anyhow", - "bs58 0.5.0", + "bs58 0.3.1", "heck", "proc-macro2 1.0.64", "quote 1.0.29", "serde", "serde_json", - "sha2 0.10.7", + "sha2 0.9.9", "syn 1.0.109", "thiserror", ] @@ -307,129 +303,6 @@ version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" -[[package]] -name = "ark-bn254" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" -dependencies = [ - "ark-ec", - "ark-ff", - "ark-std", -] - -[[package]] -name = "ark-ec" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" -dependencies = [ - "ark-ff", - "ark-poly", - "ark-serialize", - "ark-std", - "derivative", - "hashbrown 0.13.2", - "itertools", - "num-traits", - "zeroize", -] - -[[package]] -name = "ark-ff" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" -dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", - "derivative", - "digest 0.10.7", - "itertools", - "num-bigint 0.4.3", - "num-traits", - "paste", - "rustc_version", - "zeroize", -] - -[[package]] -name = "ark-ff-asm" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" -dependencies = [ - "quote 1.0.29", - "syn 1.0.109", -] - -[[package]] -name = "ark-ff-macros" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" -dependencies = [ - "num-bigint 0.4.3", - "num-traits", - "proc-macro2 1.0.64", - "quote 1.0.29", - "syn 1.0.109", -] - -[[package]] -name = "ark-poly" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" -dependencies = [ - "ark-ff", - "ark-serialize", - "ark-std", - "derivative", - "hashbrown 0.13.2", -] - -[[package]] -name = "ark-serialize" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" -dependencies = [ - "ark-serialize-derive", - "ark-std", - "digest 0.10.7", - "num-bigint 0.4.3", -] - -[[package]] -name = "ark-serialize-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" -dependencies = [ - "proc-macro2 1.0.64", - "quote 1.0.29", - "syn 1.0.109", -] - -[[package]] -name = "ark-std" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" -dependencies = [ - "num-traits", - "rand 0.8.5", -] - -[[package]] -name = "array-bytes" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ad284aeb45c13f2fb4f084de4a420ebf447423bdf9386c0540ce33cb3ef4b8c" - [[package]] name = "arrayref" version = "0.3.7" @@ -448,12 +321,6 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" -[[package]] -name = "ascii" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" - [[package]] name = "asn1-rs" version = "0.5.2" @@ -499,17 +366,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - [[package]] name = "async-compression" version = "0.3.15" @@ -561,6 +417,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + [[package]] name = "base64" version = "0.12.3" @@ -575,9 +437,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" @@ -779,18 +641,15 @@ dependencies = [ [[package]] name = "bs58" -version = "0.4.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb" [[package]] name = "bs58" -version = "0.5.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" -dependencies = [ - "tinyvec", -] +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bumpalo" @@ -912,6 +771,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" version = "2.34.0" @@ -936,7 +805,7 @@ dependencies = [ "atty", "bitflags 1.3.2", "clap_lex", - "indexmap 1.9.3", + "indexmap", "once_cell", "strsim 0.10.0", "termcolor", @@ -953,25 +822,19 @@ dependencies = [ ] [[package]] -name = "combine" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" -dependencies = [ - "ascii", - "byteorder", - "either", - "memchr", - "unreachable", -] - -[[package]] -name = "concurrent-queue" -version = "2.2.0" +name = "common-multipart-rfc7578" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +checksum = "5baee326bc603965b0f26583e1ecd7c111c41b49bd92a344897476a352798869" dependencies = [ - "crossbeam-utils", + "bytes", + "futures-core", + "futures-util", + "http", + "mime", + "mime_guess", + "rand 0.8.5", + "thiserror", ] [[package]] @@ -1007,12 +870,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "const-oid" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" - [[package]] name = "const-oid" version = "0.7.1" @@ -1041,6 +898,15 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + [[package]] name = "cpufeatures" version = "0.2.9" @@ -1119,17 +985,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -[[package]] -name = "crypto-bigint" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "crypto-common" version = "0.1.6" @@ -1156,7 +1011,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" dependencies = [ - "cipher", + "cipher 0.3.0", ] [[package]] @@ -1174,54 +1029,42 @@ dependencies = [ ] [[package]] -name = "darling" -version = "0.20.3" +name = "dashmap" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ - "darling_core", - "darling_macro", + "cfg-if", + "hashbrown 0.14.0", + "lock_api", + "once_cell", + "parking_lot_core 0.9.8", ] [[package]] -name = "darling_core" -version = "0.20.3" +name = "data-encoding" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2 1.0.64", - "quote 1.0.29", - "strsim 0.10.0", - "syn 2.0.25", -] +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] -name = "darling_macro" -version = "0.20.3" +name = "data-encoding-macro" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" dependencies = [ - "darling_core", - "quote 1.0.29", - "syn 2.0.25", + "data-encoding", + "data-encoding-macro-internal", ] [[package]] -name = "data-encoding" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" - -[[package]] -name = "der" -version = "0.4.5" +name = "data-encoding-macro-internal" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" +checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" dependencies = [ - "const-oid 0.6.2", - "crypto-bigint", + "data-encoding", + "syn 1.0.109", ] [[package]] @@ -1230,7 +1073,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" dependencies = [ - "const-oid 0.7.1", + "const-oid", ] [[package]] @@ -1253,17 +1096,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2 1.0.64", - "quote 1.0.29", - "syn 1.0.109", -] - [[package]] name = "dialoguer" version = "0.10.4" @@ -1296,6 +1128,47 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "displaydoc" version = "0.2.4" @@ -1394,19 +1267,31 @@ dependencies = [ [[package]] name = "enum-iterator" -version = "1.4.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7add3873b5dd076766ee79c8e406ad1a472c385476b9e38849f8eec24f1be689" +checksum = "2953d1df47ac0eb70086ccabf0275aa8da8591a28bd358ee2b52bd9f9e3ff9e9" dependencies = [ "enum-iterator-derive", ] [[package]] name = "enum-iterator-derive" -version = "1.2.1" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8958699f9359f0b04e691a13850d48b7de329138023876d07cbd024c2c820598" +dependencies = [ + "proc-macro2 1.0.64", + "quote 1.0.29", + "syn 1.0.109", +] + +[[package]] +name = "enum_dispatch" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" +checksum = "8f33313078bb8d4d05a2733a94ac4c2d8a0df9a2b84424ebf4f33bfc224a890e" dependencies = [ + "once_cell", "proc-macro2 1.0.64", "quote 1.0.29", "syn 2.0.25", @@ -1435,10 +1320,13 @@ dependencies = [ ] [[package]] -name = "equivalent" -version = "1.0.1" +name = "erased-serde" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +dependencies = [ + "serde", +] [[package]] name = "errno" @@ -1498,21 +1386,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.0" @@ -1618,12 +1491,21 @@ dependencies = [ ] [[package]] -name = "generic-array" -version = "0.14.7" +name = "fxhash" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" dependencies = [ - "serde", + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "serde", "typenum", "version_check", ] @@ -1664,17 +1546,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "goblin" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7666983ed0dd8d21a6f6576ee00053ca0926fb281a5522577a4dbd0f1b54143" -dependencies = [ - "log", - "plain", - "scroll", -] - [[package]] name = "h2" version = "0.3.20" @@ -1687,22 +1558,13 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap", "slab", "tokio", "tokio-util", "tracing", ] -[[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.11.2" @@ -1870,29 +1732,29 @@ dependencies = [ ] [[package]] -name = "hyper-rustls" -version = "0.23.2" +name = "hyper-multipart-rfc7578" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +checksum = "f0eb2cf73e96e9925f4bed948e763aa2901c2f1a3a5f713ee41917433ced6671" dependencies = [ + "bytes", + "common-multipart-rfc7578", + "futures-core", "http", "hyper", - "rustls", - "tokio", - "tokio-rustls", ] [[package]] -name = "hyper-tls" -version = "0.5.0" +name = "hyper-rustls" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" dependencies = [ - "bytes", + "http", "hyper", - "native-tls", + "rustls", "tokio", - "tokio-native-tls", + "tokio-rustls", ] [[package]] @@ -1918,12 +1780,6 @@ dependencies = [ "cc", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.4.0" @@ -1961,26 +1817,24 @@ dependencies = [ ] [[package]] -name = "indexmap" -version = "2.0.0" +name = "indicatif" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b" dependencies = [ - "equivalent", - "hashbrown 0.14.0", + "console", + "lazy_static", + "number_prefix", + "regex", ] [[package]] -name = "indicatif" -version = "0.17.5" +name = "inout" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ - "console", - "instant", - "number_prefix", - "portable-atomic", - "unicode-width", + "generic-array", ] [[package]] @@ -2003,6 +1857,49 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "ipfs-api-backend-hyper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9d131b408b4caafe1e7c00d410a09ad3eb7e3ab68690cf668e86904b2176b4" +dependencies = [ + "async-trait", + "base64 0.13.1", + "bytes", + "futures", + "http", + "hyper", + "hyper-multipart-rfc7578", + "ipfs-api-prelude", + "thiserror", +] + +[[package]] +name = "ipfs-api-prelude" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b74065805db266ba2c6edbd670b23c4714824a955628472b2e46cc9f3a869cb" +dependencies = [ + "async-trait", + "bytes", + "cfg-if", + "common-multipart-rfc7578", + "dirs", + "futures", + "http", + "multiaddr", + "multibase", + "serde", + "serde_json", + "serde_urlencoded", + "thiserror", + "tokio", + "tokio-util", + "tracing", + "typed-builder", + "walkdir", +] + [[package]] name = "ipnet" version = "2.8.0" @@ -2066,14 +1963,20 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -dependencies = [ - "spin", -] [[package]] name = "lexical-core" @@ -2095,10 +1998,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] -name = "libm" -version = "0.2.7" +name = "libloading" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.0", + "libc", + "redox_syscall 0.4.1", +] [[package]] name = "libsecp256k1" @@ -2148,6 +2066,12 @@ dependencies = [ "libsecp256k1-core", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -2166,9 +2090,12 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +dependencies = [ + "value-bag", +] [[package]] name = "memchr" @@ -2187,9 +2114,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.7.1" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] @@ -2221,6 +2148,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2259,35 +2196,70 @@ dependencies = [ ] [[package]] -name = "native-tls" -version = "0.2.11" +name = "multiaddr" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "2b36f567c7099511fa8612bbbb52dda2419ce0bdbacf31714e3a5ffdb766d3bd" dependencies = [ - "lazy_static", - "libc", + "arrayref", + "byteorder", + "data-encoding", "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", + "multibase", + "multihash", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint", + "url", +] + +[[package]] +name = "multibase" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +dependencies = [ + "base-x", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "multihash" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40" +dependencies = [ + "core2", + "multihash-derive", + "unsigned-varint", +] + +[[package]] +name = "multihash-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro-error", + "proc-macro2 1.0.64", + "quote 1.0.29", + "syn 1.0.109", + "synstructure", ] [[package]] name = "nix" -version = "0.26.2" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", - "memoffset 0.7.1", - "pin-utils", - "static_assertions", + "memoffset 0.6.5", ] [[package]] @@ -2356,23 +2328,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-bigint-dig" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9bc3e36fd683e004fd59c64a425e0e991616f5a8b617c3b9a933a93c168facc" -dependencies = [ - "byteorder", - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand 0.8.5", - "smallvec", - "zeroize", -] - [[package]] name = "num-complex" version = "0.2.4" @@ -2434,7 +2389,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -2453,16 +2407,7 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" dependencies = [ - "num_enum_derive 0.5.11", -] - -[[package]] -name = "num_enum" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" -dependencies = [ - "num_enum_derive 0.6.1", + "num_enum_derive", ] [[package]] @@ -2471,24 +2416,12 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 1.1.3", "proc-macro2 1.0.64", "quote 1.0.29", "syn 1.0.109", ] -[[package]] -name = "num_enum_derive" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2 1.0.64", - "quote 1.0.29", - "syn 2.0.25", -] - [[package]] name = "number_prefix" version = "0.4.0" @@ -2516,50 +2449,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -[[package]] -name = "openssl" -version = "0.10.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" -dependencies = [ - "bitflags 2.4.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2 1.0.64", - "quote 1.0.29", - "syn 2.0.25", -] - [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-sys" -version = "0.9.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "os_str_bytes" version = "6.5.1" @@ -2614,12 +2509,6 @@ dependencies = [ "windows-targets 0.48.1", ] -[[package]] -name = "paste" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" - [[package]] name = "pbkdf2" version = "0.4.0" @@ -2647,15 +2536,6 @@ dependencies = [ "base64 0.13.1", ] -[[package]] -name = "pem-rfc7468" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84e93a3b1cc0510b03020f33f21e62acdde3dcaef432edc95bea377fbd4c2cd4" -dependencies = [ - "base64ct", -] - [[package]] name = "percent-encoding" version = "2.3.0" @@ -2683,38 +2563,14 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkcs1" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "116bee8279d783c0cf370efa1a94632f2108e5ef0bb32df31f051647810a4e2c" -dependencies = [ - "der 0.4.5", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "pkcs8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" -dependencies = [ - "der 0.4.5", - "pem-rfc7468", - "pkcs1", - "spki 0.4.1", - "zeroize", -] - [[package]] name = "pkcs8" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" dependencies = [ - "der 0.5.1", - "spki 0.5.4", + "der", + "spki", "zeroize", ] @@ -2724,12 +2580,6 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" -[[package]] -name = "plain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" - [[package]] name = "polyval" version = "0.5.3" @@ -2742,12 +2592,6 @@ dependencies = [ "universal-hash", ] -[[package]] -name = "portable-atomic" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d220334a184db82b31b83f5ff093e3315280fb2b6bbc032022b2304a509aab7a" - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2765,12 +2609,36 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" dependencies = [ - "once_cell", - "toml_edit", + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2 1.0.64", + "quote 1.0.29", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2 1.0.64", + "quote 1.0.29", + "version_check", ] [[package]] @@ -2822,15 +2690,16 @@ dependencies = [ [[package]] name = "quinn" -version = "0.9.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445cbfe2382fa023c4f2f3c7e1c95c03dcc1df2bf23cebcb2b13e1402c4394d1" +checksum = "5b435e71d9bfa0d8889927231970c51fb89c58fa63bffcab117c9c7a41e5ef8f" dependencies = [ "bytes", - "pin-project-lite", + "futures-channel", + "futures-util", + "fxhash", "quinn-proto", "quinn-udp", - "rustc-hash", "rustls", "thiserror", "tokio", @@ -2840,16 +2709,17 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.9.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c10f662eee9c94ddd7135043e544f3c82fa839a1e7b865911331961b53186c" +checksum = "3fce546b9688f767a57530652488420d419a8b1f44a478b451c3d1ab6d992a55" dependencies = [ "bytes", + "fxhash", "rand 0.8.5", "ring", - "rustc-hash", "rustls", "rustls-native-certs", + "rustls-pemfile 0.2.1", "slab", "thiserror", "tinyvec", @@ -2859,15 +2729,16 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.3.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "641538578b21f5e5c8ea733b736895576d0fe329bb883b937db6f4d163dbaaf4" +checksum = "b07946277141531aea269befd949ed16b2c85a780ba1043244eda0969e538e54" dependencies = [ + "futures-util", "libc", "quinn-proto", "socket2", + "tokio", "tracing", - "windows-sys 0.42.0", ] [[package]] @@ -3007,9 +2878,9 @@ dependencies = [ [[package]] name = "rcgen" -version = "0.10.0" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" +checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" dependencies = [ "pem", "ring", @@ -3035,6 +2906,26 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom 0.2.10", + "libredox", + "thiserror", +] + [[package]] name = "regex" version = "1.9.1" @@ -3080,7 +2971,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91" dependencies = [ "async-compression", - "base64 0.21.2", + "base64 0.21.5", "bytes", "encoding_rs", "futures-core", @@ -3090,22 +2981,19 @@ dependencies = [ "http-body", "hyper", "hyper-rustls", - "hyper-tls", "ipnet", "js-sys", "log", "mime", - "native-tls", "once_cell", "percent-encoding", "pin-project-lite", "rustls", - "rustls-pemfile", + "rustls-pemfile 1.0.3", "serde", "serde_json", "serde_urlencoded", "tokio", - "tokio-native-tls", "tokio-rustls", "tokio-util", "tower-service", @@ -3162,42 +3050,13 @@ dependencies = [ [[package]] name = "rpassword" -version = "7.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322" -dependencies = [ - "libc", - "rtoolbox", - "winapi", -] - -[[package]] -name = "rsa" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e05c2603e2823634ab331437001b411b9ed11660fbc4066f3908c84a9439260d" -dependencies = [ - "byteorder", - "digest 0.9.0", - "lazy_static", - "num-bigint-dig", - "num-integer", - "num-iter", - "num-traits", - "pkcs1", - "pkcs8 0.7.6", - "rand 0.8.5", - "subtle", - "zeroize", -] - -[[package]] -name = "rtoolbox" -version = "0.0.1" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034e22c514f5c0cb8a10ff341b9b048b5ceb21591f31c8f44c43b960f9b3524a" +checksum = "2bf099a1888612545b683d2661a1940089f6c2e5a8e38979b2159da876bfd956" dependencies = [ "libc", + "serde", + "serde_json", "winapi", ] @@ -3219,12 +3078,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[package]] name = "rustc-hash" version = "1.1.0" @@ -3282,18 +3135,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 1.0.3", "schannel", "security-framework", ] +[[package]] +name = "rustls-pemfile" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9" +dependencies = [ + "base64 0.13.1", +] + [[package]] name = "rustls-pemfile" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.5", ] [[package]] @@ -3308,6 +3170,15 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.22" @@ -3323,26 +3194,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "scroll" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" -dependencies = [ - "scroll_derive", -] - -[[package]] -name = "scroll_derive" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" -dependencies = [ - "proc-macro2 1.0.64", - "quote 1.0.29", - "syn 2.0.25", -] - [[package]] name = "sct" version = "0.7.0" @@ -3417,6 +3268,15 @@ dependencies = [ "syn 2.0.25", ] +[[package]] +name = "serde_fmt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" +dependencies = [ + "serde", +] + [[package]] name = "serde_json" version = "1.0.102" @@ -3441,25 +3301,15 @@ dependencies = [ ] [[package]] -name = "serde_with" -version = "2.3.3" +name = "serde_yaml" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" dependencies = [ + "indexmap", + "ryu", "serde", - "serde_with_macros", -] - -[[package]] -name = "serde_with_macros" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" -dependencies = [ - "darling", - "proc-macro2 1.0.64", - "quote 1.0.29", - "syn 2.0.25", + "yaml-rust", ] [[package]] @@ -3592,12 +3442,12 @@ dependencies = [ [[package]] name = "solana-account-decoder" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63c62ec28eaf2f4ef06f39d549230699068e9b2171a67a8232e11993ecb86dd" +checksum = "ec36d5c2ec5469dacc4fd2bdfcaaf4b253a4814d86d88686d50fd407cf7b3330" dependencies = [ "Inflector", - "base64 0.21.2", + "base64 0.13.1", "bincode", "bs58 0.4.0", "bv", @@ -3608,6 +3458,7 @@ dependencies = [ "solana-address-lookup-table-program", "solana-config-program", "solana-sdk", + "solana-vote-program", "spl-token", "spl-token-2022", "thiserror", @@ -3616,9 +3467,9 @@ dependencies = [ [[package]] name = "solana-address-lookup-table-program" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ddbc426b2e0443c2e58c0ab721c93a788f0e97eb4f25340e4e50dd1e6978027" +checksum = "bf23fb5a4ff0e902bf94fbc63ba51b10b1f86c6bca18574b583ec3baf6383a0b" dependencies = [ "bincode", "bytemuck", @@ -3637,9 +3488,9 @@ dependencies = [ [[package]] name = "solana-clap-utils" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19777832c5623c5a1b642f35d847acaf7243124e8f4f300dbe9d387b05b4f78" +checksum = "39e6537858df8634c4cf7e9e8a84a9f1967b8983bcb4e4833cad3ae200b7170d" dependencies = [ "chrono", "clap 2.34.0", @@ -3653,44 +3504,81 @@ dependencies = [ "url", ] +[[package]] +name = "solana-cli-config" +version = "1.14.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2234deff9765c25fc6189322689d1b702490f4389680dfdef0af582856041844" +dependencies = [ + "dirs-next", + "lazy_static", + "serde", + "serde_derive", + "serde_yaml", + "solana-clap-utils", + "solana-sdk", + "url", +] + [[package]] name = "solana-client" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e3458b0fcf87b14560836a9dc1d0270fe1b4d70425235e91b94a74f4a614f0" +checksum = "e706f894fe68d518c125e27a7186d07a56f5b179d67c8fb2cf719cef8e1ee7cd" dependencies = [ + "async-mutex", "async-trait", + "base64 0.13.1", "bincode", + "bs58 0.4.0", + "bytes", + "clap 2.34.0", + "crossbeam-channel", + "enum_dispatch", "futures", "futures-util", - "indexmap 1.9.3", + "indexmap", "indicatif", + "itertools", + "jsonrpc-core", + "lazy_static", "log", "quinn", + "quinn-proto", "rand 0.7.3", + "rand_chacha 0.2.2", "rayon", - "solana-connection-cache", + "reqwest", + "rustls", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-clap-utils", + "solana-faucet", "solana-measure", "solana-metrics", - "solana-pubsub-client", - "solana-quic-client", - "solana-rpc-client", - "solana-rpc-client-api", - "solana-rpc-client-nonce-utils", + "solana-net-utils", "solana-sdk", "solana-streamer", - "solana-thin-client", - "solana-tpu-client", - "solana-udp-client", + "solana-transaction-status", + "solana-version", + "solana-vote-program", + "spl-token-2022", "thiserror", "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite", + "url", ] [[package]] name = "solana-config-program" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac78caf77ffe8cc8c108b2e424f5e710f640777f3d78faf2ac7535008a39f5a" +checksum = "645c2d438fdfa4f5774c70fb0eeb2325caa073c838a229ef6a876c65c8703294" dependencies = [ "bincode", "chrono", @@ -3701,35 +3589,38 @@ dependencies = [ ] [[package]] -name = "solana-connection-cache" -version = "1.16.3" +name = "solana-faucet" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "964e4b517d80543e9ff0676bb1700f5011e8588795f4e68fb8ab343c87eefad4" +checksum = "3ba3e5e2acc09b2fcb54957d05c0943b194d48f825f879fc2cf5d255e2608b05" dependencies = [ - "async-trait", "bincode", - "futures-util", - "indexmap 1.9.3", + "byteorder", + "clap 2.34.0", + "crossbeam-channel", "log", - "rand 0.7.3", - "rayon", - "rcgen", - "solana-measure", + "serde", + "serde_derive", + "solana-clap-utils", + "solana-cli-config", + "solana-logger", "solana-metrics", "solana-sdk", + "solana-version", + "spl-memo", "thiserror", "tokio", ] [[package]] name = "solana-frozen-abi" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c272bd949536a92f0fc4d9572bf72b35b3545fc1f6ee031e44f9d075809055d" +checksum = "23b4953578272ac0fadec245e85e83ae86454611f0c0a7fff7d906835124bdcf" dependencies = [ - "ahash 0.8.3", + "ahash 0.7.6", "blake3", - "block-buffer 0.10.4", + "block-buffer 0.9.0", "bs58 0.4.0", "bv", "byteorder", @@ -3737,6 +3628,7 @@ dependencies = [ "either", "generic-array", "getrandom 0.1.16", + "hashbrown 0.12.3", "im", "lazy_static", "log", @@ -3756,21 +3648,21 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f84be4b6dd2cc4e8ad5baa54a23018c8936ec32322ebcffd88355631700292a" +checksum = "57892538250428ad3dc3cbe05f6cd75ad14f4f16734fcb91bc7cd5fbb63d6315" dependencies = [ "proc-macro2 1.0.64", "quote 1.0.29", "rustc_version", - "syn 2.0.25", + "syn 1.0.109", ] [[package]] name = "solana-logger" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3cb934e8c9015e86cd9c7382ea3083578d1c0813a351644cfdabe3009591b03" +checksum = "06aa701c49493e93085dd1e800c05475baca15a9d4d527b59794f2ed0b66e055" dependencies = [ "env_logger", "lazy_static", @@ -3779,9 +3671,9 @@ dependencies = [ [[package]] name = "solana-measure" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a038b70fac9cd5529839efc258e6453f0018d34937a414cd030318916d6dba6" +checksum = "f7300180957635b33c88bd6844a5dff4f1f5c6352d0861ee7845eab84185aa6a" dependencies = [ "log", "solana-sdk", @@ -3789,9 +3681,9 @@ dependencies = [ [[package]] name = "solana-metrics" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cca14a16eac701e20bda3e103e3d078074a18e83e126f90d918e141379eade8d" +checksum = "2960981c4bbe9177dafe986542ba11a10afcae320f4201aa809cd5b650e202e1" dependencies = [ "crossbeam-channel", "gethostname", @@ -3803,9 +3695,9 @@ dependencies = [ [[package]] name = "solana-net-utils" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509c3d5bc7fe8dbcc25b3238d7cd4a0994c39207260b7b5271a3110ea0ac5f75" +checksum = "31062ce5ddceb92bdb78df2eaf33e9889c1519e8a8d89baa783e2d08a76cfc62" dependencies = [ "bincode", "clap 3.2.25", @@ -3825,11 +3717,11 @@ dependencies = [ [[package]] name = "solana-perf" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a65308af752a91eddf06c7b7bb5e5d6296ec8cd8de5a1cbebd61f53f45a808c" +checksum = "23b2b84a3d7a24523b9117c0ae4608f1e561ae492638acea2bb2960a0c0c8eb6" dependencies = [ - "ahash 0.8.3", + "ahash 0.7.6", "bincode", "bv", "caps", @@ -3852,20 +3744,16 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "476510cb86b9602a793582788f5e23a9cca11929d3880b7427a67142b1e4a430" +checksum = "3f99052873619df68913cb8e92e28ff251a5483828925e87fa97ba15a9cbad51" dependencies = [ - "ark-bn254", - "ark-ec", - "ark-ff", - "ark-serialize", - "array-bytes", - "base64 0.21.2", + "base64 0.13.1", "bincode", "bitflags 1.3.2", "blake3", - "borsh 0.10.3", + "borsh 0.9.3", + "borsh-derive 0.9.3", "bs58 0.4.0", "bv", "bytemuck", @@ -3880,8 +3768,7 @@ dependencies = [ "libc", "libsecp256k1", "log", - "memoffset 0.9.0", - "num-bigint 0.4.3", + "memoffset 0.6.5", "num-derive", "num-traits", "parking_lot 0.12.1", @@ -3906,186 +3793,71 @@ dependencies = [ [[package]] name = "solana-program-runtime" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8311e581ff6406c84ce8ed5d4f1316cf091f723b4823a1ece3e36be6cfb3d69c" +checksum = "4d57d0b6ef85b50f9ad6b9a75fc9d5051dc26f8b1a4ddf03656e3d603e139eb3" dependencies = [ - "base64 0.21.2", + "base64 0.13.1", "bincode", "eager", "enum-iterator", "itertools", "libc", + "libloading", "log", "num-derive", "num-traits", - "percentage", "rand 0.7.3", "rustc_version", "serde", "solana-frozen-abi", "solana-frozen-abi-macro", "solana-measure", - "solana-metrics", - "solana-sdk", - "solana_rbpf", - "thiserror", -] - -[[package]] -name = "solana-pubsub-client" -version = "1.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5274196946dfef625ec905f7834e7d45b8367364f8eaf99e2c754951da6b972d" -dependencies = [ - "crossbeam-channel", - "futures-util", - "log", - "reqwest", - "semver", - "serde", - "serde_derive", - "serde_json", - "solana-account-decoder", - "solana-rpc-client-api", - "solana-sdk", - "thiserror", - "tokio", - "tokio-stream", - "tokio-tungstenite", - "tungstenite", - "url", -] - -[[package]] -name = "solana-quic-client" -version = "1.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b27ad60edef844f182cd7071e653731ec16b3a319524448935a1183f6b99b80" -dependencies = [ - "async-mutex", - "async-trait", - "futures", - "itertools", - "lazy_static", - "log", - "quinn", - "quinn-proto", - "quinn-udp", - "rcgen", - "rustls", - "solana-connection-cache", - "solana-measure", - "solana-metrics", - "solana-net-utils", - "solana-rpc-client-api", - "solana-sdk", - "solana-streamer", - "thiserror", - "tokio", -] - -[[package]] -name = "solana-rayon-threadlimit" -version = "1.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "441bde92d8befd3a698e54c35bff63a396f1e3e5e85754d85a5308a8f5d0328a" -dependencies = [ - "lazy_static", - "num_cpus", -] - -[[package]] -name = "solana-remote-wallet" -version = "1.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b8820ed78c726c9359248a8fb6456657ce6feca2ff31ffac1286f55bee99e8" -dependencies = [ - "console", - "dialoguer", - "log", - "num-derive", - "num-traits", - "parking_lot 0.12.1", - "qstring", - "semver", - "solana-sdk", - "thiserror", - "uriparse", -] - -[[package]] -name = "solana-rpc-client" -version = "1.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baeb95820862d14c1391dfda9a3173b0509f1b17ebd1090b3778fac1743ab69" -dependencies = [ - "async-trait", - "base64 0.21.2", - "bincode", - "bs58 0.4.0", - "indicatif", - "log", - "reqwest", - "semver", - "serde", - "serde_derive", - "serde_json", - "solana-account-decoder", - "solana-rpc-client-api", + "solana-metrics", "solana-sdk", - "solana-transaction-status", - "solana-version", - "solana-vote-program", - "tokio", + "thiserror", ] [[package]] -name = "solana-rpc-client-api" -version = "1.16.3" +name = "solana-rayon-threadlimit" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29009927e289fc5ccd19cec05780dc8465eb65e52922087cf769e57d72c0b7b5" +checksum = "10e1d068ba8080ca1e41703c600cc9b263ff7ce26b6811cd83221723ae0d10ae" dependencies = [ - "base64 0.21.2", - "bs58 0.4.0", - "jsonrpc-core", - "reqwest", - "semver", - "serde", - "serde_derive", - "serde_json", - "solana-account-decoder", - "solana-sdk", - "solana-transaction-status", - "solana-version", - "spl-token-2022", - "thiserror", + "lazy_static", + "num_cpus", ] [[package]] -name = "solana-rpc-client-nonce-utils" -version = "1.16.3" +name = "solana-remote-wallet" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df466014e9768f4741be00acea0067bde11a2ec1162a12ebf896960990a2e6b8" +checksum = "661cd486da7419134663f1c3684d71d3fd6d13b8e557da23070f4c920b1d2baa" dependencies = [ - "clap 2.34.0", - "solana-clap-utils", - "solana-rpc-client", + "console", + "dialoguer", + "log", + "num-derive", + "num-traits", + "parking_lot 0.12.1", + "qstring", + "semver", "solana-sdk", "thiserror", + "uriparse", ] [[package]] name = "solana-sdk" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "352b70bb14d8968d5484aa73a1aede3acc816f10a0b264c6599108c5dd6b647b" +checksum = "edb47da3e18cb669f6ace0b40cee0610e278903783e0c9f7fce1e1beb881a1b7" dependencies = [ "assert_matches", - "base64 0.21.2", + "base64 0.13.1", "bincode", "bitflags 1.3.2", - "borsh 0.10.3", + "borsh 0.9.3", "bs58 0.4.0", "bytemuck", "byteorder", @@ -4104,7 +3876,6 @@ dependencies = [ "memmap2", "num-derive", "num-traits", - "num_enum 0.6.1", "pbkdf2 0.11.0", "qstring", "rand 0.7.3", @@ -4115,7 +3886,6 @@ dependencies = [ "serde_bytes", "serde_derive", "serde_json", - "serde_with", "sha2 0.10.7", "sha3 0.10.8", "solana-frozen-abi", @@ -4130,39 +3900,35 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e38a884c027b0759d0969efc1253f3b8798f9d5fbef2eb158cdb70763619d2f3" +checksum = "7d41a09b9cecd0a4df63c78a192adee99ebf2d3757c19713a68246e1d9789c7c" dependencies = [ "bs58 0.4.0", "proc-macro2 1.0.64", "quote 1.0.29", "rustversion", - "syn 2.0.25", + "syn 1.0.109", ] [[package]] name = "solana-streamer" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13b87bd090a462765b6e3196e6c22cc0edebf8942fb4a6de9a807ce3d8d5d436" +checksum = "a2ffb2c6918eda6aa8b18219790b7a4e4d74914aeae97cb1a0e09fdb943b18cc" dependencies = [ - "async-channel", - "bytes", "crossbeam-channel", "futures-util", "histogram", - "indexmap 1.9.3", + "indexmap", "itertools", "libc", "log", "nix", "pem", "percentage", - "pkcs8 0.8.0", + "pkcs8", "quinn", - "quinn-proto", - "quinn-udp", "rand 0.7.3", "rcgen", "rustls", @@ -4174,54 +3940,14 @@ dependencies = [ "x509-parser", ] -[[package]] -name = "solana-thin-client" -version = "1.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8dc82e52a443249c5b1df3ddd7273306c81fde2c8057cc398e0fbd0fae7a47" -dependencies = [ - "bincode", - "log", - "rayon", - "solana-connection-cache", - "solana-rpc-client", - "solana-rpc-client-api", - "solana-sdk", -] - -[[package]] -name = "solana-tpu-client" -version = "1.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a09c139e796337646ba4f013a849555f50d35ae7278461d685a429c29f6295f" -dependencies = [ - "async-trait", - "bincode", - "futures-util", - "indexmap 1.9.3", - "indicatif", - "log", - "rand 0.7.3", - "rayon", - "solana-connection-cache", - "solana-measure", - "solana-metrics", - "solana-pubsub-client", - "solana-rpc-client", - "solana-rpc-client-api", - "solana-sdk", - "thiserror", - "tokio", -] - [[package]] name = "solana-transaction-status" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284227b302a68b0c384f46cb95e5472d39e7c7094d6079c4e5bd2f133f6920ff" +checksum = "df1a6ee396d436ae4ee36350043c3cb34ad66b7515f045c1e5006695559d88ac" dependencies = [ "Inflector", - "base64 0.21.2", + "base64 0.13.1", "bincode", "borsh 0.9.3", "bs58 0.4.0", @@ -4232,7 +3958,10 @@ dependencies = [ "serde_json", "solana-account-decoder", "solana-address-lookup-table-program", + "solana-measure", + "solana-metrics", "solana-sdk", + "solana-vote-program", "spl-associated-token-account", "spl-memo", "spl-token", @@ -4240,26 +3969,11 @@ dependencies = [ "thiserror", ] -[[package]] -name = "solana-udp-client" -version = "1.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23aa72c84646a65727b63ff2988147062a792b569591351f06c0e6014ca52de9" -dependencies = [ - "async-trait", - "solana-connection-cache", - "solana-net-utils", - "solana-sdk", - "solana-streamer", - "thiserror", - "tokio", -] - [[package]] name = "solana-version" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "036b2c0f4b3dfbe48d96c0f5e9be0fadd019bf46327013475bbf3b8ae9870dfe" +checksum = "d177dc97f7facd8fbc3148f3d44a9ff5bbbc72c1db7e2889dc4911ae641cea8a" dependencies = [ "log", "rustc_version", @@ -4273,9 +3987,9 @@ dependencies = [ [[package]] name = "solana-vote-program" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85fe8c3382ac0c050c2224037fc8be990f713526e6b136f3a8da9464e2e1a506" +checksum = "6280815d28c90ea8f51c8eb2026258e8693cab5a8456ee7b207a791b20f9c576" dependencies = [ "bincode", "log", @@ -4287,7 +4001,6 @@ dependencies = [ "solana-frozen-abi", "solana-frozen-abi-macro", "solana-metrics", - "solana-program", "solana-program-runtime", "solana-sdk", "thiserror", @@ -4295,15 +4008,17 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" -version = "1.16.3" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02a4c38e1cf77cc046a48d0e515ec3fe654d9c3ba49790523f2d8fd28a5e51d3" +checksum = "7ab38abd096769f79fd8e3fe8465070f04742395db724606a5263c8ebc215567" dependencies = [ "aes-gcm-siv", - "base64 0.21.2", + "arrayref", + "base64 0.13.1", "bincode", "bytemuck", "byteorder", + "cipher 0.4.4", "curve25519-dalek", "getrandom 0.1.16", "itertools", @@ -4322,40 +4037,12 @@ dependencies = [ "zeroize", ] -[[package]] -name = "solana_rbpf" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3082ec3a1d4ef7879eb5b84916d5acde057abd59733eec3647e0ab8885283ef" -dependencies = [ - "byteorder", - "combine", - "goblin", - "hash32", - "libc", - "log", - "rand 0.8.5", - "rustc-demangle", - "scroll", - "thiserror", - "winapi", -] - [[package]] name = "spin" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "spki" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" -dependencies = [ - "der 0.4.5", -] - [[package]] name = "spki" version = "0.5.4" @@ -4363,14 +4050,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" dependencies = [ "base64ct", - "der 0.5.1", + "der", ] [[package]] name = "spl-associated-token-account" -version = "1.1.3" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978dba3bcbe88d0c2c58366c254d9ea41c5f73357e72fc0bdee4d6b5fc99c8f4" +checksum = "fbc000f0fdf1f12f99d77d398137c1751345b18c88258ce0f99b7872cf6c9bd6" dependencies = [ "assert_matches", "borsh 0.9.3", @@ -4401,22 +4088,22 @@ dependencies = [ "bytemuck", "num-derive", "num-traits", - "num_enum 0.5.11", + "num_enum", "solana-program", "thiserror", ] [[package]] name = "spl-token-2022" -version = "0.6.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0043b590232c400bad5ee9eb983ced003d15163c4c5d56b090ac6d9a57457b47" +checksum = "0edb869dbe159b018f17fb9bfa67118c30f232d7f54a73742bc96794dff77ed8" dependencies = [ "arrayref", "bytemuck", "num-derive", "num-traits", - "num_enum 0.5.11", + "num_enum", "solana-program", "solana-zk-token-sdk", "spl-memo", @@ -4455,52 +4142,138 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" [[package]] -name = "switchboard-common" -version = "0.8.15" +name = "sval" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15df12a8db7c216a04b4b438f90d50d5335cd38f161b56389c9f5c9d96d0873" + +[[package]] +name = "sval_buffer" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e80556bc8acea0446e574ce542ad6114a76a0237f28a842bc01ca3ea98f479" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d93d2259edb1d7b4316179f0a98c62e3ffc726f47ab200e07cfe382771f57b8" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532f7f882226f7a5a4656f5151224aaebf8217e0d539cb1595b831bace921343" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e03bd8aa0ae6ee018f7ae95c9714577687a4415bd1a5f19b26e34695f7e072" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_ref" +version = "2.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723a9a346c6d6eb3374ebe8ea3848e61d40d1f9f46635604137e19a1a4262c52" +checksum = "75ed054f2fb8c2a0ab5d36c1ec57b412919700099fc5e32ad8e7a38b23e1a9e1" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff191c4ff05b67e3844c161021427646cde5d6624597958be158357d9200586" +dependencies = [ + "serde", + "sval", + "sval_buffer", + "sval_fmt", +] + +[[package]] +name = "switchboard-common" +version = "0.10.1" dependencies = [ + "async-trait", + "base64 0.21.5", "envy", + "futures", "getrandom 0.2.10", "hex", - "rand 0.8.5", - "reqwest", + "ipfs-api-backend-hyper", + "ipfs-api-prelude", + "libc", + "log", + "proc-macro2 1.0.64", + "quote 1.0.29", "serde", "serde_json", "sgx-quote", "sha2 0.10.7", + "syn 2.0.25", ] [[package]] name = "switchboard-solana" -version = "0.28.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa9c6634ad316592b84930a923efe0be920b1bd94d61237a90b596ebd926c40" +version = "0.27.43" dependencies = [ "anchor-client", "anchor-lang", "anchor-spl", + "base64 0.21.5", "bincode", "bytemuck", "chrono", "cron", + "dashmap", + "futures", "hex", - "rand 0.8.5", - "reqwest", - "rsa", + "kv-log-macro", + "log", "rust_decimal", "serde", "serde_json", "sgx-quote", + "sha2 0.10.7", + "solana-account-decoder", "solana-address-lookup-table-program", "solana-client", "solana-program", "superslice", "switchboard-common", + "switchboard-solana-macros", "tokio", "url", ] +[[package]] +name = "switchboard-solana-macros" +version = "0.2.0" +dependencies = [ + "proc-macro2 1.0.64", + "quote 1.0.29", + "syn 2.0.25", +] + [[package]] name = "syn" version = "0.15.44" @@ -4713,16 +4486,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.23.4" @@ -4784,23 +4547,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_datetime" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" - -[[package]] -name = "toml_edit" -version = "0.19.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f8751d9c1b03c6500c387e96f81f815a4f8e72d142d2d4a9ffa6fedd51ddee7" -dependencies = [ - "indexmap 2.0.0", - "toml_datetime", - "winnow", -] - [[package]] name = "tower-service" version = "0.3.2" @@ -4814,7 +4560,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -4868,12 +4613,32 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "typed-builder" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c" +dependencies = [ + "proc-macro2 1.0.64", + "quote 1.0.29", + "syn 1.0.109", +] + [[package]] name = "typenum" version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.13" @@ -4930,13 +4695,10 @@ dependencies = [ ] [[package]] -name = "unreachable" -version = "1.0.0" +name = "unsigned-varint" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -dependencies = [ - "void", -] +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" [[package]] name = "untrusted" @@ -4978,10 +4740,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" [[package]] -name = "vcpkg" -version = "0.2.15" +name = "value-bag" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a72e1902dde2bd6441347de2b70b7f5d59bf157c6c62f0c44572607a1d55bbe" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +checksum = "07ba39dc791ecb35baad371a3fc04c6eab688c04937d2e0ac6c22b612c0357bf" +dependencies = [ + "erased-serde", + "serde", + "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e06c10810a57bbf45778d023d432a50a1daa7d185991ae06bcfb6c654d0945" +dependencies = [ + "sval", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", +] [[package]] name = "vec_map" @@ -4996,10 +4788,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] -name = "void" -version = "1.0.2" +name = "walkdir" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] [[package]] name = "want" @@ -5163,21 +4959,6 @@ dependencies = [ "windows-targets 0.48.1", ] -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-sys" version = "0.45.0" @@ -5310,15 +5091,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" -[[package]] -name = "winnow" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" -dependencies = [ - "memchr", -] - [[package]] name = "winreg" version = "0.10.1" @@ -5355,6 +5127,15 @@ dependencies = [ "time 0.3.23", ] +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + [[package]] name = "yasna" version = "0.5.2" diff --git a/examples/functions/04_randomness_callback/switchboard-function/Cargo.toml b/examples/functions/04_randomness_callback/switchboard-function/Cargo.toml index 1d082e1cb..5c86bf12a 100644 --- a/examples/functions/04_randomness_callback/switchboard-function/Cargo.toml +++ b/examples/functions/04_randomness_callback/switchboard-function/Cargo.toml @@ -12,5 +12,7 @@ path = "src/main.rs" [dependencies] tokio = "^1" futures = "0.3" -# switchboard-solana = "0.28.19" -switchboard-solana = { version = "0.28.19", path = "../../../../rust/switchboard-solana" } +# switchboard-solana = "0.28.43" +switchboard-solana = { path = "../../../../rust/switchboard-solana", features = [ + "macros", +] } diff --git a/examples/functions/04_randomness_callback/switchboard-function/src/main.rs b/examples/functions/04_randomness_callback/switchboard-function/src/main.rs index 8d3471d85..a0174f4e5 100644 --- a/examples/functions/04_randomness_callback/switchboard-function/src/main.rs +++ b/examples/functions/04_randomness_callback/switchboard-function/src/main.rs @@ -6,20 +6,13 @@ pub use switchboard_solana::prelude::*; mod params; pub use params::*; -#[tokio::main(worker_threads = 12)] -async fn main() { - // First, initialize the runner instance with a freshly generated Gramine keypair - let runner = FunctionRunner::new_from_cluster(Cluster::Devnet, None).unwrap(); - +#[switchboard_function] +pub async fn randomness_callback( + runner: FunctionRunner, + params: Vec, +) -> Result, SbFunctionError> { // parse and validate user provided request params - let params = ContainerParams::decode( - &runner - .function_request_data - .as_ref() - .unwrap() - .container_params, - ) - .unwrap(); + let params = ContainerParams::decode(¶ms).unwrap(); // Determine the final result let mut bytes: [u8; 1] = [0u8; 1]; @@ -59,7 +52,5 @@ async fn main() { // Should be under 700 bytes after serialization let ixs: Vec = vec![user_settle_ixn]; - // Finally, emit the signed quote and partially signed transaction to the functionRunner oracle - // The functionRunner oracle will use the last outputted word to stdout as the serialized result. This is what gets executed on-chain. - runner.emit(ixs).await.unwrap(); + Ok(ixs) } diff --git a/examples/functions/04_randomness_callback/switchboard-function/src/params.rs b/examples/functions/04_randomness_callback/switchboard-function/src/params.rs index ee9a25c98..07fa56429 100644 --- a/examples/functions/04_randomness_callback/switchboard-function/src/params.rs +++ b/examples/functions/04_randomness_callback/switchboard-function/src/params.rs @@ -7,7 +7,7 @@ pub struct ContainerParams { } impl ContainerParams { - pub fn decode(container_params: &Vec) -> std::result::Result { + pub fn decode(container_params: &Vec) -> std::result::Result { let params = String::from_utf8(container_params.clone()).unwrap(); let mut program_id: Pubkey = Pubkey::default(); @@ -18,28 +18,28 @@ impl ContainerParams { let pair: Vec<&str> = env_pair.splitn(2, '=').collect(); if pair.len() == 2 { match pair[0] { - "PID" => program_id = Pubkey::from_str(pair[1]).unwrap(), - "MAX_GUESS" => max_guess = pair[1].parse::().unwrap(), - "USER" => user_key = Pubkey::from_str(pair[1]).unwrap(), + "PID" => { + program_id = Pubkey::from_str(pair[1]).unwrap(); + } + "MAX_GUESS" => { + max_guess = pair[1].parse::().unwrap(); + } + "USER" => { + user_key = Pubkey::from_str(pair[1]).unwrap(); + } _ => {} } } } if program_id == Pubkey::default() { - return Err(SwitchboardClientError::CustomMessage( - "PID cannot be undefined".to_string(), - )); + return Err(SbFunctionError::FunctionError(100)); } if max_guess == 0 { - return Err(SwitchboardClientError::CustomMessage( - "MAX_GUESS must be greater than 0".to_string(), - )); + return Err(SbFunctionError::FunctionError(101)); } if user_key == Pubkey::default() { - return Err(SwitchboardClientError::CustomMessage( - "USER_KEY cannot be undefined".to_string(), - )); + return Err(SbFunctionError::FunctionError(102)); } Ok(Self { diff --git a/examples/functions/05_raffle_program/Cargo.toml b/examples/functions/05_raffle_program/Cargo.toml index ad3a63f0e..8ae4fe9f9 100644 --- a/examples/functions/05_raffle_program/Cargo.toml +++ b/examples/functions/05_raffle_program/Cargo.toml @@ -28,5 +28,5 @@ cpi = ["no-entrypoint"] default = [] [dependencies] -switchboard-solana = "0.28.19" -# switchboard-solana = { version = "0.28.19", path = "../../../rust/switchboard-solana" } +switchboard-solana = "0.28.43" +# switchboard-solana = { path = "../../../rust/switchboard-solana" } diff --git a/examples/functions/05_raffle_program/package.json b/examples/functions/05_raffle_program/package.json index f8f707571..6e1c92c7a 100644 --- a/examples/functions/05_raffle_program/package.json +++ b/examples/functions/05_raffle_program/package.json @@ -7,8 +7,8 @@ }, "dependencies": { "@coral-xyz/anchor": "^0.28.0", - "@switchboard-xyz/common": "^2.3.3", - "@switchboard-xyz/solana.js": "^2.5.0" + "@switchboard-xyz/common": "*", + "@switchboard-xyz/solana.js": "*" }, "devDependencies": { "@types/bn.js": "^5.1.0", diff --git a/examples/functions/05_raffle_program/switchboard-function/Cargo.lock b/examples/functions/05_raffle_program/switchboard-function/Cargo.lock index c40fb0c02..929080fdd 100644 --- a/examples/functions/05_raffle_program/switchboard-function/Cargo.lock +++ b/examples/functions/05_raffle_program/switchboard-function/Cargo.lock @@ -34,7 +34,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" dependencies = [ "cfg-if", - "cipher", + "cipher 0.3.0", "cpufeatures", "opaque-debug", ] @@ -47,7 +47,7 @@ checksum = "589c637f0e68c877bbd59a4599bbe849cac8e5f3e4b5a3ebae8f528cd218dcdc" dependencies = [ "aead", "aes", - "cipher", + "cipher 0.3.0", "ctr", "polyval", "subtle", @@ -72,7 +72,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if", - "getrandom 0.2.10", "once_cell", "version_check", ] @@ -103,9 +102,9 @@ dependencies = [ [[package]] name = "anchor-attribute-access-control" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa5be5b72abea167f87c868379ba3c2be356bfca9e6f474fd055fa0f7eeb4f2" +checksum = "2d5e1a413b311b039d29b61d0dbb401c9dbf04f792497ceca87593454bf6d7dd" dependencies = [ "anchor-syn", "anyhow", @@ -117,13 +116,13 @@ dependencies = [ [[package]] name = "anchor-attribute-account" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f468970344c7c9f9d03b4da854fd7c54f21305059f53789d0045c1dd803f0018" +checksum = "cca9aeaf633c6e2365fed0525dcac68610be58eee5dc69d3b86fe0b1d4b320b9" dependencies = [ "anchor-syn", "anyhow", - "bs58 0.5.0", + "bs58 0.4.0", "proc-macro2 1.0.63", "quote 1.0.28", "rustversion", @@ -132,9 +131,9 @@ dependencies = [ [[package]] name = "anchor-attribute-constant" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59948e7f9ef8144c2aefb3f32a40c5fce2798baeec765ba038389e82301017ef" +checksum = "788e44f9e8501dabeb6f9229da0f3268fb2ae3208912608ffaa056a72031296f" dependencies = [ "anchor-syn", "proc-macro2 1.0.63", @@ -143,9 +142,9 @@ dependencies = [ [[package]] name = "anchor-attribute-error" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc753c9d1c7981cb8948cf7e162fb0f64558999c0413058e2d43df1df5448086" +checksum = "ea0c4d8c7e4a2605ede6fcdced9690288b2f74e24768619a85229d57e597bc97" dependencies = [ "anchor-syn", "proc-macro2 1.0.63", @@ -155,9 +154,9 @@ dependencies = [ [[package]] name = "anchor-attribute-event" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38b4e172ba1b52078f53fdc9f11e3dc0668ad27997838a0aad2d148afac8c97" +checksum = "7a3b07d5c5d87b5edc72428b447b8e9ee1143b83dd1afc6a6b1d352c6a6164d8" dependencies = [ "anchor-syn", "anyhow", @@ -168,9 +167,9 @@ dependencies = [ [[package]] name = "anchor-attribute-program" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eebd21543606ab61e2d83d9da37d24d3886a49f390f9c43a1964735e8c0f0d5" +checksum = "b22ad0445115dbea5869b1d062da49ae125abed9132fc20c33227f25e42dfa6b" dependencies = [ "anchor-syn", "anyhow", @@ -181,28 +180,26 @@ dependencies = [ [[package]] name = "anchor-client" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8434a6bf33efba0c93157f7fa2fafac658cb26ab75396886dcedd87c2a8ad445" +checksum = "04c06e06497b5b4f392845e0d04dde8374fd244fa2832dd0e5c27bfd99cb0342" dependencies = [ "anchor-lang", "anyhow", - "futures", "regex", "serde", "solana-account-decoder", "solana-client", "solana-sdk", "thiserror", - "tokio", "url", ] [[package]] name = "anchor-derive-accounts" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec4720d899b3686396cced9508f23dab420f1308344456ec78ef76f98fda42af" +checksum = "48daeff6781ba2f02961b0ad211feb9a2de75af345d42c62b1a252fd4dfb0724" dependencies = [ "anchor-syn", "anyhow", @@ -213,9 +210,9 @@ dependencies = [ [[package]] name = "anchor-derive-space" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f495e85480bd96ddeb77b71d499247c7d4e8b501e75ecb234e9ef7ae7bd6552a" +checksum = "c4fe2886f92c4f33ec1b2b8b2b43ca1b9070cf4929e63c7eaaa09a9f2c0d5123" dependencies = [ "proc-macro2 1.0.63", "quote 1.0.28", @@ -224,9 +221,9 @@ dependencies = [ [[package]] name = "anchor-lang" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d2d4b20100f1310a774aba3471ef268e5c4ba4d5c28c0bbe663c2658acbc414" +checksum = "dbbe5d1c7c057c6d63b4f2f538a320e4a22111126c9966340c3d9490e2f15ed1" dependencies = [ "anchor-attribute-access-control", "anchor-attribute-account", @@ -239,18 +236,17 @@ dependencies = [ "arrayref", "base64 0.13.1", "bincode", - "borsh 0.10.3", + "borsh 0.9.3", "bytemuck", - "getrandom 0.2.10", "solana-program", "thiserror", ] [[package]] name = "anchor-spl" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78f860599da1c2354e7234c768783049eb42e2f54509ecfc942d2e0076a2da7b" +checksum = "75cc8066fbd45e0e03edf48342c79265aa34ca76cefeace48ef6c402b6946665" dependencies = [ "anchor-lang", "solana-program", @@ -261,18 +257,18 @@ dependencies = [ [[package]] name = "anchor-syn" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a125e4b0cc046cfec58f5aa25038e34cf440151d58f0db3afc55308251fe936d" +checksum = "11cb31fe143aedb36fc41409ea072aa0b840cbea727e62eb2ff6e7b6cea036ff" dependencies = [ "anyhow", - "bs58 0.5.0", - "heck 0.3.3", + "bs58 0.3.1", + "heck", "proc-macro2 1.0.63", "quote 1.0.28", "serde", "serde_json", - "sha2 0.10.7", + "sha2 0.9.9", "syn 1.0.109", "thiserror", ] @@ -307,129 +303,6 @@ version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" -[[package]] -name = "ark-bn254" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" -dependencies = [ - "ark-ec", - "ark-ff", - "ark-std", -] - -[[package]] -name = "ark-ec" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" -dependencies = [ - "ark-ff", - "ark-poly", - "ark-serialize", - "ark-std", - "derivative", - "hashbrown 0.13.2", - "itertools", - "num-traits", - "zeroize", -] - -[[package]] -name = "ark-ff" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" -dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", - "derivative", - "digest 0.10.7", - "itertools", - "num-bigint 0.4.3", - "num-traits", - "paste", - "rustc_version", - "zeroize", -] - -[[package]] -name = "ark-ff-asm" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" -dependencies = [ - "quote 1.0.28", - "syn 1.0.109", -] - -[[package]] -name = "ark-ff-macros" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" -dependencies = [ - "num-bigint 0.4.3", - "num-traits", - "proc-macro2 1.0.63", - "quote 1.0.28", - "syn 1.0.109", -] - -[[package]] -name = "ark-poly" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" -dependencies = [ - "ark-ff", - "ark-serialize", - "ark-std", - "derivative", - "hashbrown 0.13.2", -] - -[[package]] -name = "ark-serialize" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" -dependencies = [ - "ark-serialize-derive", - "ark-std", - "digest 0.10.7", - "num-bigint 0.4.3", -] - -[[package]] -name = "ark-serialize-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" -dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.28", - "syn 1.0.109", -] - -[[package]] -name = "ark-std" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" -dependencies = [ - "num-traits", - "rand 0.8.5", -] - -[[package]] -name = "array-bytes" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ad284aeb45c13f2fb4f084de4a420ebf447423bdf9386c0540ce33cb3ef4b8c" - [[package]] name = "arrayref" version = "0.3.7" @@ -448,12 +321,6 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" -[[package]] -name = "ascii" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" - [[package]] name = "asn1-rs" version = "0.5.2" @@ -467,7 +334,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.22", + "time", ] [[package]] @@ -499,17 +366,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" -[[package]] -name = "async-channel" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - [[package]] name = "async-compression" version = "0.3.15" @@ -561,6 +417,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + [[package]] name = "base64" version = "0.12.3" @@ -575,9 +437,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" @@ -600,6 +462,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + [[package]] name = "bitmaps" version = "2.1.0" @@ -773,18 +641,15 @@ dependencies = [ [[package]] name = "bs58" -version = "0.4.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb" [[package]] name = "bs58" -version = "0.5.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" -dependencies = [ - "tinyvec", -] +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bumpalo" @@ -892,18 +757,17 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", - "time 0.1.45", "wasm-bindgen", - "winapi", + "windows-targets 0.48.1", ] [[package]] @@ -915,6 +779,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" version = "2.34.0" @@ -923,7 +797,7 @@ checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", - "bitflags", + "bitflags 1.3.2", "strsim 0.8.0", "textwrap 0.11.0", "unicode-width", @@ -937,9 +811,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "atty", - "bitflags", + "bitflags 1.3.2", "clap_lex", - "indexmap 1.9.3", + "indexmap", "once_cell", "strsim 0.10.0", "termcolor", @@ -956,25 +830,19 @@ dependencies = [ ] [[package]] -name = "combine" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" -dependencies = [ - "ascii", - "byteorder", - "either", - "memchr", - "unreachable", -] - -[[package]] -name = "concurrent-queue" -version = "2.2.0" +name = "common-multipart-rfc7578" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +checksum = "5baee326bc603965b0f26583e1ecd7c111c41b49bd92a344897476a352798869" dependencies = [ - "crossbeam-utils", + "bytes", + "futures-core", + "futures-util", + "http", + "mime", + "mime_guess", + "rand 0.8.5", + "thiserror", ] [[package]] @@ -1038,6 +906,15 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + [[package]] name = "cpufeatures" version = "0.2.8" @@ -1142,7 +1019,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" dependencies = [ - "cipher", + "cipher 0.3.0", ] [[package]] @@ -1160,45 +1037,43 @@ dependencies = [ ] [[package]] -name = "darling" -version = "0.20.1" +name = "dashmap" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ - "darling_core", - "darling_macro", + "cfg-if", + "hashbrown 0.14.0", + "lock_api", + "once_cell", + "parking_lot_core 0.9.8", ] [[package]] -name = "darling_core" -version = "0.20.1" +name = "data-encoding" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2 1.0.63", - "quote 1.0.28", - "strsim 0.10.0", - "syn 2.0.22", -] +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] -name = "darling_macro" -version = "0.20.1" +name = "data-encoding-macro" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" +checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" dependencies = [ - "darling_core", - "quote 1.0.28", - "syn 2.0.22", + "data-encoding", + "data-encoding-macro-internal", ] [[package]] -name = "data-encoding" -version = "2.4.0" +name = "data-encoding-macro-internal" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" +dependencies = [ + "data-encoding", + "syn 1.0.109", +] [[package]] name = "der" @@ -1229,17 +1104,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.28", - "syn 1.0.109", -] - [[package]] name = "dialoguer" version = "0.10.4" @@ -1272,6 +1136,47 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "displaydoc" version = "0.2.4" @@ -1370,19 +1275,31 @@ dependencies = [ [[package]] name = "enum-iterator" -version = "1.4.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7add3873b5dd076766ee79c8e406ad1a472c385476b9e38849f8eec24f1be689" +checksum = "2953d1df47ac0eb70086ccabf0275aa8da8591a28bd358ee2b52bd9f9e3ff9e9" dependencies = [ "enum-iterator-derive", ] [[package]] name = "enum-iterator-derive" -version = "1.2.1" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8958699f9359f0b04e691a13850d48b7de329138023876d07cbd024c2c820598" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 1.0.109", +] + +[[package]] +name = "enum_dispatch" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" +checksum = "8f33313078bb8d4d05a2733a94ac4c2d8a0df9a2b84424ebf4f33bfc224a890e" dependencies = [ + "once_cell", "proc-macro2 1.0.63", "quote 1.0.28", "syn 2.0.22", @@ -1402,10 +1319,22 @@ dependencies = [ ] [[package]] -name = "equivalent" -version = "1.0.0" +name = "envy" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f47e0157f2cb54f5ae1bd371b30a2ae4311e1c028f575cd4e81de7353215965" +dependencies = [ + "serde", +] + +[[package]] +name = "erased-serde" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +dependencies = [ + "serde", +] [[package]] name = "errno" @@ -1449,12 +1378,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - [[package]] name = "flate2" version = "1.0.26" @@ -1590,6 +1513,15 @@ dependencies = [ "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1638,21 +1570,10 @@ dependencies = [ ] [[package]] -name = "goblin" -version = "0.5.4" +name = "h2" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7666983ed0dd8d21a6f6576ee00053ca0926fb281a5522577a4dbd0f1b54143" -dependencies = [ - "log", - "plain", - "scroll", -] - -[[package]] -name = "h2" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ "bytes", "fnv", @@ -1660,22 +1581,13 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap", "slab", "tokio", "tokio-util", "tracing", ] -[[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.11.2" @@ -1718,12 +1630,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "hermit-abi" version = "0.1.19" @@ -1857,6 +1763,19 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-multipart-rfc7578" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb2cf73e96e9925f4bed948e763aa2901c2f1a3a5f713ee41917433ced6671" +dependencies = [ + "bytes", + "common-multipart-rfc7578", + "futures-core", + "http", + "hyper", +] + [[package]] name = "hyper-rustls" version = "0.23.2" @@ -1906,12 +1825,6 @@ dependencies = [ "cc", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.4.0" @@ -1949,26 +1862,24 @@ dependencies = [ ] [[package]] -name = "indexmap" -version = "2.0.0" +name = "indicatif" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b" dependencies = [ - "equivalent", - "hashbrown 0.14.0", + "console", + "lazy_static", + "number_prefix", + "regex", ] [[package]] -name = "indicatif" -version = "0.17.5" +name = "inout" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ - "console", - "instant", - "number_prefix", - "portable-atomic", - "unicode-width", + "generic-array", ] [[package]] @@ -1991,6 +1902,49 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "ipfs-api-backend-hyper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9d131b408b4caafe1e7c00d410a09ad3eb7e3ab68690cf668e86904b2176b4" +dependencies = [ + "async-trait", + "base64 0.13.1", + "bytes", + "futures", + "http", + "hyper", + "hyper-multipart-rfc7578", + "ipfs-api-prelude", + "thiserror", +] + +[[package]] +name = "ipfs-api-prelude" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b74065805db266ba2c6edbd670b23c4714824a955628472b2e46cc9f3a869cb" +dependencies = [ + "async-trait", + "bytes", + "cfg-if", + "common-multipart-rfc7578", + "dirs", + "futures", + "http", + "multiaddr", + "multibase", + "serde", + "serde_json", + "serde_urlencoded", + "thiserror", + "tokio", + "tokio-util", + "tracing", + "typed-builder", + "walkdir", +] + [[package]] name = "ipnet" version = "2.8.0" @@ -2066,6 +2020,15 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -2079,7 +2042,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" dependencies = [ "arrayvec 0.5.2", - "bitflags", + "bitflags 1.3.2", "cfg-if", "ryu", "static_assertions", @@ -2091,6 +2054,27 @@ version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall 0.4.1", +] + [[package]] name = "libsecp256k1" version = "0.6.0" @@ -2139,6 +2123,12 @@ dependencies = [ "libsecp256k1-core", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -2157,9 +2147,12 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +dependencies = [ + "value-bag", +] [[package]] name = "memchr" @@ -2178,9 +2171,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.7.1" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] @@ -2212,6 +2205,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2250,10 +2253,59 @@ dependencies = [ ] [[package]] -name = "multimap" -version = "0.8.3" +name = "multiaddr" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b36f567c7099511fa8612bbbb52dda2419ce0bdbacf31714e3a5ffdb766d3bd" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", + "log", + "multibase", + "multihash", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint", + "url", +] + +[[package]] +name = "multibase" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +dependencies = [ + "base-x", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "multihash" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40" +dependencies = [ + "core2", + "multihash-derive", + "unsigned-varint", +] + +[[package]] +name = "multihash-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro-error", + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 1.0.109", + "synstructure", +] [[package]] name = "native-tls" @@ -2275,16 +2327,14 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.2" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", - "memoffset 0.7.1", - "pin-utils", - "static_assertions", + "memoffset 0.6.5", ] [[package]] @@ -2432,16 +2482,7 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" dependencies = [ - "num_enum_derive 0.5.11", -] - -[[package]] -name = "num_enum" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" -dependencies = [ - "num_enum_derive 0.6.1", + "num_enum_derive", ] [[package]] @@ -2450,24 +2491,12 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 1.1.3", "proc-macro2 1.0.63", "quote 1.0.28", "syn 1.0.109", ] -[[package]] -name = "num_enum_derive" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2 1.0.63", - "quote 1.0.28", - "syn 2.0.22", -] - [[package]] name = "number_prefix" version = "0.4.0" @@ -2501,7 +2530,7 @@ version = "0.10.55" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "foreign-types", "libc", @@ -2593,12 +2622,6 @@ dependencies = [ "windows-targets 0.48.1", ] -[[package]] -name = "paste" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" - [[package]] name = "pbkdf2" version = "0.4.0" @@ -2685,16 +2708,6 @@ dependencies = [ "sha2 0.10.7", ] -[[package]] -name = "petgraph" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" -dependencies = [ - "fixedbitset", - "indexmap 1.9.3", -] - [[package]] name = "pin-project-lite" version = "0.2.9" @@ -2724,12 +2737,6 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" -[[package]] -name = "plain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" - [[package]] name = "polyval" version = "0.5.3" @@ -2742,12 +2749,6 @@ dependencies = [ "universal-hash", ] -[[package]] -name = "portable-atomic" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2755,32 +2756,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] -name = "prettyplease" -version = "0.1.25" +name = "proc-macro-crate" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ - "proc-macro2 1.0.63", - "syn 1.0.109", + "toml", ] [[package]] name = "proc-macro-crate" -version = "0.1.5" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" dependencies = [ + "thiserror", "toml", ] [[package]] -name = "proc-macro-crate" -version = "1.3.1" +name = "proc-macro-error" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ - "once_cell", - "toml_edit", + "proc-macro-error-attr", + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "version_check", ] [[package]] @@ -2803,58 +2818,25 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.9" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +checksum = "f4fdd22f3b9c31b53c060df4a0613a1c7f062d4115a2b984dd15b1858f7e340d" dependencies = [ "bytes", "prost-derive", ] -[[package]] -name = "prost-build" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" -dependencies = [ - "bytes", - "heck 0.4.1", - "itertools", - "lazy_static", - "log", - "multimap", - "petgraph", - "prettyplease", - "prost", - "prost-types", - "pulldown-cmark", - "pulldown-cmark-to-cmark", - "regex", - "syn 1.0.109", - "tempfile", - "which", -] - [[package]] name = "prost-derive" -version = "0.11.9" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32" dependencies = [ "anyhow", "itertools", "proc-macro2 1.0.63", "quote 1.0.28", - "syn 1.0.109", -] - -[[package]] -name = "prost-types" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" -dependencies = [ - "prost", + "syn 2.0.22", ] [[package]] @@ -2877,26 +2859,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "pulldown-cmark" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" -dependencies = [ - "bitflags", - "memchr", - "unicase", -] - -[[package]] -name = "pulldown-cmark-to-cmark" -version = "10.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0194e6e1966c23cc5fd988714f85b18d548d773e81965413555d96569931833d" -dependencies = [ - "pulldown-cmark", -] - [[package]] name = "qstring" version = "0.7.2" @@ -2908,15 +2870,16 @@ dependencies = [ [[package]] name = "quinn" -version = "0.9.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445cbfe2382fa023c4f2f3c7e1c95c03dcc1df2bf23cebcb2b13e1402c4394d1" +checksum = "5b435e71d9bfa0d8889927231970c51fb89c58fa63bffcab117c9c7a41e5ef8f" dependencies = [ "bytes", - "pin-project-lite", + "futures-channel", + "futures-util", + "fxhash", "quinn-proto", "quinn-udp", - "rustc-hash", "rustls", "thiserror", "tokio", @@ -2926,16 +2889,17 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.9.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c10f662eee9c94ddd7135043e544f3c82fa839a1e7b865911331961b53186c" +checksum = "3fce546b9688f767a57530652488420d419a8b1f44a478b451c3d1ab6d992a55" dependencies = [ "bytes", + "fxhash", "rand 0.8.5", "ring", - "rustc-hash", "rustls", "rustls-native-certs", + "rustls-pemfile 0.2.1", "slab", "thiserror", "tinyvec", @@ -2945,15 +2909,16 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.3.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "641538578b21f5e5c8ea733b736895576d0fe329bb883b937db6f4d163dbaaf4" +checksum = "b07946277141531aea269befd949ed16b2c85a780ba1043244eda0969e538e54" dependencies = [ + "futures-util", "libc", "quinn-proto", "socket2", + "tokio", "tracing", - "windows-sys 0.42.0", ] [[package]] @@ -3084,13 +3049,13 @@ dependencies = [ [[package]] name = "rcgen" -version = "0.10.0" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" +checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" dependencies = [ "pem", "ring", - "time 0.3.22", + "time", "yasna", ] @@ -3100,7 +3065,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -3109,7 +3074,27 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom 0.2.10", + "libredox", + "thiserror", ] [[package]] @@ -3145,7 +3130,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91" dependencies = [ "async-compression", - "base64 0.21.2", + "base64 0.21.5", "bytes", "encoding_rs", "futures-core", @@ -3165,7 +3150,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls", - "rustls-pemfile", + "rustls-pemfile 1.0.3", "serde", "serde_json", "serde_urlencoded", @@ -3227,22 +3212,13 @@ dependencies = [ [[package]] name = "rpassword" -version = "7.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322" -dependencies = [ - "libc", - "rtoolbox", - "winapi", -] - -[[package]] -name = "rtoolbox" -version = "0.0.1" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034e22c514f5c0cb8a10ff341b9b048b5ceb21591f31c8f44c43b960f9b3524a" +checksum = "2bf099a1888612545b683d2661a1940089f6c2e5a8e38979b2159da876bfd956" dependencies = [ "libc", + "serde", + "serde_json", "winapi", ] @@ -3264,12 +3240,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[package]] name = "rustc-hash" version = "1.1.0" @@ -3300,7 +3270,7 @@ version = "0.37.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", @@ -3327,18 +3297,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 1.0.3", "schannel", "security-framework", ] +[[package]] +name = "rustls-pemfile" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9" +dependencies = [ + "base64 0.13.1", +] + [[package]] name = "rustls-pemfile" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.5", ] [[package]] @@ -3353,6 +3332,15 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.21" @@ -3368,26 +3356,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "scroll" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" -dependencies = [ - "scroll_derive", -] - -[[package]] -name = "scroll_derive" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" -dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.28", - "syn 2.0.22", -] - [[package]] name = "sct" version = "0.7.0" @@ -3410,7 +3378,7 @@ version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -3435,9 +3403,9 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.164" +version = "1.0.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "d614f89548720367ded108b3c843be93f3a341e22d5674ca0dd5cd57f34926af" dependencies = [ "serde_derive", ] @@ -3453,15 +3421,24 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "d4fe589678c688e44177da4f27152ee2d190757271dc7f1d5b6b9f68d869d641" dependencies = [ "proc-macro2 1.0.63", "quote 1.0.28", "syn 2.0.22", ] +[[package]] +name = "serde_fmt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" +dependencies = [ + "serde", +] + [[package]] name = "serde_json" version = "1.0.99" @@ -3486,25 +3463,15 @@ dependencies = [ ] [[package]] -name = "serde_with" -version = "2.3.3" +name = "serde_yaml" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" dependencies = [ + "indexmap", + "ryu", "serde", - "serde_with_macros", -] - -[[package]] -name = "serde_with_macros" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" -dependencies = [ - "darling", - "proc-macro2 1.0.63", - "quote 1.0.28", - "syn 2.0.22", + "yaml-rust", ] [[package]] @@ -3637,12 +3604,12 @@ dependencies = [ [[package]] name = "solana-account-decoder" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380584cb468a1eb2ea79495c0c574ca09a11bf6796093b97a48a94cd98fe5b30" +checksum = "ec36d5c2ec5469dacc4fd2bdfcaaf4b253a4814d86d88686d50fd407cf7b3330" dependencies = [ "Inflector", - "base64 0.21.2", + "base64 0.13.1", "bincode", "bs58 0.4.0", "bv", @@ -3653,6 +3620,7 @@ dependencies = [ "solana-address-lookup-table-program", "solana-config-program", "solana-sdk", + "solana-vote-program", "spl-token", "spl-token-2022", "thiserror", @@ -3661,9 +3629,9 @@ dependencies = [ [[package]] name = "solana-address-lookup-table-program" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dcdcbe2a61849b7692ac9eb6ad567ea4f333c36272d5d12de554aa2f60fa792" +checksum = "bf23fb5a4ff0e902bf94fbc63ba51b10b1f86c6bca18574b583ec3baf6383a0b" dependencies = [ "bincode", "bytemuck", @@ -3682,9 +3650,9 @@ dependencies = [ [[package]] name = "solana-clap-utils" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fe8a1443f3efac9c351c0b55efa39df488e73bcdd512272cb39e58198dcf9cc" +checksum = "39e6537858df8634c4cf7e9e8a84a9f1967b8983bcb4e4833cad3ae200b7170d" dependencies = [ "chrono", "clap 2.34.0", @@ -3698,44 +3666,81 @@ dependencies = [ "url", ] +[[package]] +name = "solana-cli-config" +version = "1.14.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2234deff9765c25fc6189322689d1b702490f4389680dfdef0af582856041844" +dependencies = [ + "dirs-next", + "lazy_static", + "serde", + "serde_derive", + "serde_yaml", + "solana-clap-utils", + "solana-sdk", + "url", +] + [[package]] name = "solana-client" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46e6294e67101c8df185e9c371293ff2502bf5b35d4d70eb68472eae135692e5" +checksum = "e706f894fe68d518c125e27a7186d07a56f5b179d67c8fb2cf719cef8e1ee7cd" dependencies = [ + "async-mutex", "async-trait", + "base64 0.13.1", "bincode", + "bs58 0.4.0", + "bytes", + "clap 2.34.0", + "crossbeam-channel", + "enum_dispatch", "futures", "futures-util", - "indexmap 1.9.3", + "indexmap", "indicatif", + "itertools", + "jsonrpc-core", + "lazy_static", "log", "quinn", + "quinn-proto", "rand 0.7.3", + "rand_chacha 0.2.2", "rayon", - "solana-connection-cache", + "reqwest", + "rustls", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-clap-utils", + "solana-faucet", "solana-measure", "solana-metrics", - "solana-pubsub-client", - "solana-quic-client", - "solana-rpc-client", - "solana-rpc-client-api", - "solana-rpc-client-nonce-utils", + "solana-net-utils", "solana-sdk", "solana-streamer", - "solana-thin-client", - "solana-tpu-client", - "solana-udp-client", + "solana-transaction-status", + "solana-version", + "solana-vote-program", + "spl-token-2022", "thiserror", "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite", + "url", ] [[package]] name = "solana-config-program" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e44cd8bbbc468503ca8d337c91a6f6049ced080be31854d866a25974f1b90619" +checksum = "645c2d438fdfa4f5774c70fb0eeb2325caa073c838a229ef6a876c65c8703294" dependencies = [ "bincode", "chrono", @@ -3746,35 +3751,38 @@ dependencies = [ ] [[package]] -name = "solana-connection-cache" -version = "1.16.1" +name = "solana-faucet" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e953284f00e9b706032fe36b30054f3c804f37a363fac7d8cb1753a1737cf20b" +checksum = "3ba3e5e2acc09b2fcb54957d05c0943b194d48f825f879fc2cf5d255e2608b05" dependencies = [ - "async-trait", "bincode", - "futures-util", - "indexmap 1.9.3", + "byteorder", + "clap 2.34.0", + "crossbeam-channel", "log", - "rand 0.7.3", - "rayon", - "rcgen", - "solana-measure", + "serde", + "serde_derive", + "solana-clap-utils", + "solana-cli-config", + "solana-logger", "solana-metrics", "solana-sdk", + "solana-version", + "spl-memo", "thiserror", "tokio", ] [[package]] name = "solana-frozen-abi" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eea8be57163366de9ffee3652cd42ea02fd5cca672408722f1426eb0d234a330" +checksum = "23b4953578272ac0fadec245e85e83ae86454611f0c0a7fff7d906835124bdcf" dependencies = [ - "ahash 0.8.3", + "ahash 0.7.6", "blake3", - "block-buffer 0.10.4", + "block-buffer 0.9.0", "bs58 0.4.0", "bv", "byteorder", @@ -3782,6 +3790,7 @@ dependencies = [ "either", "generic-array", "getrandom 0.1.16", + "hashbrown 0.12.3", "im", "lazy_static", "log", @@ -3801,21 +3810,21 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4121f91307234cec8c8d8cd2d7ec171881c07db2222335e8c840d555ebe89cc" +checksum = "57892538250428ad3dc3cbe05f6cd75ad14f4f16734fcb91bc7cd5fbb63d6315" dependencies = [ "proc-macro2 1.0.63", "quote 1.0.28", "rustc_version", - "syn 2.0.22", + "syn 1.0.109", ] [[package]] name = "solana-logger" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f590904a129707c5bf6b9f2e198e49ce8984e802dad26babd2c406a4e898b0ce" +checksum = "06aa701c49493e93085dd1e800c05475baca15a9d4d527b59794f2ed0b66e055" dependencies = [ "env_logger", "lazy_static", @@ -3824,9 +3833,9 @@ dependencies = [ [[package]] name = "solana-measure" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26976359ec46d158ce2880d5a31bca4b08e971d29d03c25e9ba80f9a3d42b28e" +checksum = "f7300180957635b33c88bd6844a5dff4f1f5c6352d0861ee7845eab84185aa6a" dependencies = [ "log", "solana-sdk", @@ -3834,9 +3843,9 @@ dependencies = [ [[package]] name = "solana-metrics" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d97a86ca9bc1c33b77f98502ef0ec133823ebbb813fc60e10c6cf6377bbbdf2" +checksum = "2960981c4bbe9177dafe986542ba11a10afcae320f4201aa809cd5b650e202e1" dependencies = [ "crossbeam-channel", "gethostname", @@ -3848,9 +3857,9 @@ dependencies = [ [[package]] name = "solana-net-utils" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a63f59abfa214c43b2b0d0360f7a50c180a0e86ea9a16ad7598ca0c9d8843483" +checksum = "31062ce5ddceb92bdb78df2eaf33e9889c1519e8a8d89baa783e2d08a76cfc62" dependencies = [ "bincode", "clap 3.2.25", @@ -3870,11 +3879,11 @@ dependencies = [ [[package]] name = "solana-perf" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7219016f9a81863decafd5256ec0d32d57a8c4e9529f9134fd8727684cc0936" +checksum = "23b2b84a3d7a24523b9117c0ae4608f1e561ae492638acea2bb2960a0c0c8eb6" dependencies = [ - "ahash 0.8.3", + "ahash 0.7.6", "bincode", "bv", "caps", @@ -3897,20 +3906,16 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ac28d05adeff2212cdec76dfacc6eb631d69d065b1b83c063a1fab505d5e62" +checksum = "3f99052873619df68913cb8e92e28ff251a5483828925e87fa97ba15a9cbad51" dependencies = [ - "ark-bn254", - "ark-ec", - "ark-ff", - "ark-serialize", - "array-bytes", - "base64 0.21.2", + "base64 0.13.1", "bincode", - "bitflags", + "bitflags 1.3.2", "blake3", - "borsh 0.10.3", + "borsh 0.9.3", + "borsh-derive 0.9.3", "bs58 0.4.0", "bv", "bytemuck", @@ -3925,8 +3930,7 @@ dependencies = [ "libc", "libsecp256k1", "log", - "memoffset 0.9.0", - "num-bigint 0.4.3", + "memoffset 0.6.5", "num-derive", "num-traits", "parking_lot 0.12.1", @@ -3951,196 +3955,81 @@ dependencies = [ [[package]] name = "solana-program-runtime" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03cb661d9fe32ec33ba8df554827becd5bcc1758392194420899771344177fb1" +checksum = "4d57d0b6ef85b50f9ad6b9a75fc9d5051dc26f8b1a4ddf03656e3d603e139eb3" dependencies = [ - "base64 0.21.2", + "base64 0.13.1", "bincode", "eager", "enum-iterator", "itertools", "libc", + "libloading", "log", "num-derive", "num-traits", - "percentage", "rand 0.7.3", "rustc_version", "serde", "solana-frozen-abi", - "solana-frozen-abi-macro", - "solana-measure", - "solana-metrics", - "solana-sdk", - "solana_rbpf", - "thiserror", -] - -[[package]] -name = "solana-pubsub-client" -version = "1.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a503785ba377f33dd5b1fac75cb60c086ba625c5305f0bf3e687240cdcc7381f" -dependencies = [ - "crossbeam-channel", - "futures-util", - "log", - "reqwest", - "semver", - "serde", - "serde_derive", - "serde_json", - "solana-account-decoder", - "solana-rpc-client-api", - "solana-sdk", - "thiserror", - "tokio", - "tokio-stream", - "tokio-tungstenite", - "tungstenite", - "url", -] - -[[package]] -name = "solana-quic-client" -version = "1.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ede431a588575037db080835f09e9436bb9d5f3b3e19a5592eca3af13da369" -dependencies = [ - "async-mutex", - "async-trait", - "futures", - "itertools", - "lazy_static", - "log", - "quinn", - "quinn-proto", - "quinn-udp", - "rcgen", - "rustls", - "solana-connection-cache", - "solana-measure", - "solana-metrics", - "solana-net-utils", - "solana-rpc-client-api", - "solana-sdk", - "solana-streamer", - "thiserror", - "tokio", -] - -[[package]] -name = "solana-raffle-program" -version = "0.1.0" -dependencies = [ - "futures", - "switchboard-solana", - "switchboard-utils", - "tokio", -] - -[[package]] -name = "solana-rayon-threadlimit" -version = "1.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4131723cc61f9981c3fa792567c658cf8fa64366331647835c3b88ba0685bad9" -dependencies = [ - "lazy_static", - "num_cpus", -] - -[[package]] -name = "solana-remote-wallet" -version = "1.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c74894d82e6adcd95398dd4d190e6f303e424d47841b20f822a5ec27d5b77473" -dependencies = [ - "console", - "dialoguer", - "log", - "num-derive", - "num-traits", - "parking_lot 0.12.1", - "qstring", - "semver", - "solana-sdk", - "thiserror", - "uriparse", -] - -[[package]] -name = "solana-rpc-client" -version = "1.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4e9519b92e003d763ab2123ac099c32a56f66951cd810d4fa3615a800300860" -dependencies = [ - "async-trait", - "base64 0.21.2", - "bincode", - "bs58 0.4.0", - "indicatif", - "log", - "reqwest", - "semver", - "serde", - "serde_derive", - "serde_json", - "solana-account-decoder", - "solana-rpc-client-api", + "solana-frozen-abi-macro", + "solana-measure", + "solana-metrics", "solana-sdk", - "solana-transaction-status", - "solana-version", - "solana-vote-program", + "thiserror", +] + +[[package]] +name = "solana-raffle-program" +version = "0.1.0" +dependencies = [ + "futures", + "switchboard-solana", + "switchboard-utils", "tokio", ] [[package]] -name = "solana-rpc-client-api" -version = "1.16.1" +name = "solana-rayon-threadlimit" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac5556080cb9a1c70b782de622ee5840d6e1a256c65ab35a3b8542656ffe69a0" +checksum = "10e1d068ba8080ca1e41703c600cc9b263ff7ce26b6811cd83221723ae0d10ae" dependencies = [ - "base64 0.21.2", - "bs58 0.4.0", - "jsonrpc-core", - "reqwest", - "semver", - "serde", - "serde_derive", - "serde_json", - "solana-account-decoder", - "solana-sdk", - "solana-transaction-status", - "solana-version", - "spl-token-2022", - "thiserror", + "lazy_static", + "num_cpus", ] [[package]] -name = "solana-rpc-client-nonce-utils" -version = "1.16.1" +name = "solana-remote-wallet" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbe69e5bab1a8afc475c1aab69ce53360e76fafa0f5efcc5ce151298be763653" +checksum = "661cd486da7419134663f1c3684d71d3fd6d13b8e557da23070f4c920b1d2baa" dependencies = [ - "clap 2.34.0", - "solana-clap-utils", - "solana-rpc-client", + "console", + "dialoguer", + "log", + "num-derive", + "num-traits", + "parking_lot 0.12.1", + "qstring", + "semver", "solana-sdk", "thiserror", + "uriparse", ] [[package]] name = "solana-sdk" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3aa2d54c0e9109d1bf9edafbd86d645217776df783814397f79c3929cf4316ba" +checksum = "edb47da3e18cb669f6ace0b40cee0610e278903783e0c9f7fce1e1beb881a1b7" dependencies = [ "assert_matches", - "base64 0.21.2", + "base64 0.13.1", "bincode", - "bitflags", - "borsh 0.10.3", + "bitflags 1.3.2", + "borsh 0.9.3", "bs58 0.4.0", "bytemuck", "byteorder", @@ -4159,7 +4048,6 @@ dependencies = [ "memmap2", "num-derive", "num-traits", - "num_enum 0.6.1", "pbkdf2 0.11.0", "qstring", "rand 0.7.3", @@ -4170,7 +4058,6 @@ dependencies = [ "serde_bytes", "serde_derive", "serde_json", - "serde_with", "sha2 0.10.7", "sha3 0.10.8", "solana-frozen-abi", @@ -4185,29 +4072,27 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa991e6d6ae7c57ef9fc56f964b22f3bae6ba6c144ccb07b0fe07e06a3efc47c" +checksum = "7d41a09b9cecd0a4df63c78a192adee99ebf2d3757c19713a68246e1d9789c7c" dependencies = [ "bs58 0.4.0", "proc-macro2 1.0.63", "quote 1.0.28", "rustversion", - "syn 2.0.22", + "syn 1.0.109", ] [[package]] name = "solana-streamer" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2500570c1fe541d3e36c3ce318f25dab24dfd6aeab216afafa5c7c161d4979c8" +checksum = "a2ffb2c6918eda6aa8b18219790b7a4e4d74914aeae97cb1a0e09fdb943b18cc" dependencies = [ - "async-channel", - "bytes", "crossbeam-channel", "futures-util", "histogram", - "indexmap 1.9.3", + "indexmap", "itertools", "libc", "log", @@ -4216,8 +4101,6 @@ dependencies = [ "percentage", "pkcs8", "quinn", - "quinn-proto", - "quinn-udp", "rand 0.7.3", "rcgen", "rustls", @@ -4229,54 +4112,14 @@ dependencies = [ "x509-parser", ] -[[package]] -name = "solana-thin-client" -version = "1.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2fd4ae4d27790ae211f16a6e85a02585b7cae7057f8d555bad3762b4901c" -dependencies = [ - "bincode", - "log", - "rayon", - "solana-connection-cache", - "solana-rpc-client", - "solana-rpc-client-api", - "solana-sdk", -] - -[[package]] -name = "solana-tpu-client" -version = "1.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e56bfe97fb1ab0eb44abb623272648bea404d309e584ba6f8e981e6626cfb0cb" -dependencies = [ - "async-trait", - "bincode", - "futures-util", - "indexmap 1.9.3", - "indicatif", - "log", - "rand 0.7.3", - "rayon", - "solana-connection-cache", - "solana-measure", - "solana-metrics", - "solana-pubsub-client", - "solana-rpc-client", - "solana-rpc-client-api", - "solana-sdk", - "thiserror", - "tokio", -] - [[package]] name = "solana-transaction-status" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5331f3dfa4a8228dd69b6954859d6aafdd3234b24802690c1f7446bc37df6d" +checksum = "df1a6ee396d436ae4ee36350043c3cb34ad66b7515f045c1e5006695559d88ac" dependencies = [ "Inflector", - "base64 0.21.2", + "base64 0.13.1", "bincode", "borsh 0.9.3", "bs58 0.4.0", @@ -4287,7 +4130,10 @@ dependencies = [ "serde_json", "solana-account-decoder", "solana-address-lookup-table-program", + "solana-measure", + "solana-metrics", "solana-sdk", + "solana-vote-program", "spl-associated-token-account", "spl-memo", "spl-token", @@ -4295,26 +4141,11 @@ dependencies = [ "thiserror", ] -[[package]] -name = "solana-udp-client" -version = "1.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "371e23c982638eeabab1a62bf637c70648b730fc807378042214382c3b550000" -dependencies = [ - "async-trait", - "solana-connection-cache", - "solana-net-utils", - "solana-sdk", - "solana-streamer", - "thiserror", - "tokio", -] - [[package]] name = "solana-version" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbad2a5e055b53a7d41e52f98963bcef1ee6ce782f90f1d4ea9237cae1ee87ee" +checksum = "d177dc97f7facd8fbc3148f3d44a9ff5bbbc72c1db7e2889dc4911ae641cea8a" dependencies = [ "log", "rustc_version", @@ -4328,9 +4159,9 @@ dependencies = [ [[package]] name = "solana-vote-program" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c27089add49014dc9a917ddb95d5af0ab31bd15308adb4bdce78fd72b52d787b" +checksum = "6280815d28c90ea8f51c8eb2026258e8693cab5a8456ee7b207a791b20f9c576" dependencies = [ "bincode", "log", @@ -4342,7 +4173,6 @@ dependencies = [ "solana-frozen-abi", "solana-frozen-abi-macro", "solana-metrics", - "solana-program", "solana-program-runtime", "solana-sdk", "thiserror", @@ -4350,16 +4180,17 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" -version = "1.16.1" +version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05aa69c3f19df466a68a26f009e9dc39de671bf022c66fbbfab2d1c021b62a97" +checksum = "7ab38abd096769f79fd8e3fe8465070f04742395db724606a5263c8ebc215567" dependencies = [ "aes-gcm-siv", "arrayref", - "base64 0.21.2", + "base64 0.13.1", "bincode", "bytemuck", "byteorder", + "cipher 0.4.4", "curve25519-dalek", "getrandom 0.1.16", "itertools", @@ -4378,25 +4209,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "solana_rbpf" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ae90c406f0a2d4a15f08d16c8b64f37997a57611fec0a89f1277854166996e8" -dependencies = [ - "byteorder", - "combine", - "goblin", - "hash32", - "libc", - "log", - "rand 0.8.5", - "rustc-demangle", - "scroll", - "thiserror", - "winapi", -] - [[package]] name = "spin" version = "0.5.2" @@ -4415,9 +4227,9 @@ dependencies = [ [[package]] name = "spl-associated-token-account" -version = "1.1.3" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978dba3bcbe88d0c2c58366c254d9ea41c5f73357e72fc0bdee4d6b5fc99c8f4" +checksum = "fbc000f0fdf1f12f99d77d398137c1751345b18c88258ce0f99b7872cf6c9bd6" dependencies = [ "assert_matches", "borsh 0.9.3", @@ -4448,22 +4260,22 @@ dependencies = [ "bytemuck", "num-derive", "num-traits", - "num_enum 0.5.11", + "num_enum", "solana-program", "thiserror", ] [[package]] name = "spl-token-2022" -version = "0.6.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0043b590232c400bad5ee9eb983ced003d15163c4c5d56b090ac6d9a57457b47" +checksum = "0edb869dbe159b018f17fb9bfa67118c30f232d7f54a73742bc96794dff77ed8" dependencies = [ "arrayref", "bytemuck", "num-derive", "num-traits", - "num_enum 0.5.11", + "num_enum", "solana-program", "solana-zk-token-sdk", "spl-memo", @@ -4501,52 +4313,152 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" +[[package]] +name = "sval" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15df12a8db7c216a04b4b438f90d50d5335cd38f161b56389c9f5c9d96d0873" + +[[package]] +name = "sval_buffer" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e80556bc8acea0446e574ce542ad6114a76a0237f28a842bc01ca3ea98f479" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d93d2259edb1d7b4316179f0a98c62e3ffc726f47ab200e07cfe382771f57b8" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532f7f882226f7a5a4656f5151224aaebf8217e0d539cb1595b831bace921343" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e03bd8aa0ae6ee018f7ae95c9714577687a4415bd1a5f19b26e34695f7e072" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_ref" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75ed054f2fb8c2a0ab5d36c1ec57b412919700099fc5e32ad8e7a38b23e1a9e1" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff191c4ff05b67e3844c161021427646cde5d6624597958be158357d9200586" +dependencies = [ + "serde", + "sval", + "sval_buffer", + "sval_fmt", +] + [[package]] name = "switchboard-common" -version = "0.8.6" +version = "0.10.1" dependencies = [ + "async-trait", + "base64 0.21.5", + "envy", + "futures", "getrandom 0.2.10", "hex", + "ipfs-api-backend-hyper", + "ipfs-api-prelude", + "libc", + "log", + "proc-macro2 1.0.63", + "quote 1.0.28", "serde", "serde_json", "sgx-quote", "sha2 0.10.7", + "syn 2.0.22", ] [[package]] name = "switchboard-solana" -version = "0.28.0" +version = "0.27.43" dependencies = [ "anchor-client", "anchor-lang", "anchor-spl", + "base64 0.21.5", "bincode", "bytemuck", "chrono", "cron", + "dashmap", + "futures", "hex", + "kv-log-macro", + "log", "rust_decimal", + "serde", + "serde_json", "sgx-quote", + "sha2 0.10.7", + "solana-account-decoder", "solana-address-lookup-table-program", "solana-client", "solana-program", "superslice", "switchboard-common", + "switchboard-solana-macros", "tokio", + "url", +] + +[[package]] +name = "switchboard-solana-macros" +version = "0.2.0" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 2.0.22", ] [[package]] name = "switchboard-utils" -version = "0.8.0" +version = "0.9.0" dependencies = [ "bytes", "bytestring", + "chrono", "futures-channel", "futures-util", "jsonpath-rust", "prost", - "prost-build", "reqwest", + "rust_decimal", "serde", "serde_derive", "serde_json", @@ -4664,17 +4576,6 @@ dependencies = [ "syn 2.0.22", ] -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - [[package]] name = "time" version = "0.3.22" @@ -4838,23 +4739,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_datetime" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" - -[[package]] -name = "toml_edit" -version = "0.19.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7" -dependencies = [ - "indexmap 2.0.0", - "toml_datetime", - "winnow", -] - [[package]] name = "tower-service" version = "0.3.2" @@ -4868,7 +4752,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -4922,6 +4805,17 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "typed-builder" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c" +dependencies = [ + "proc-macro2 1.0.63", + "quote 1.0.28", + "syn 1.0.109", +] + [[package]] name = "typenum" version = "1.16.0" @@ -4999,13 +4893,10 @@ dependencies = [ ] [[package]] -name = "unreachable" -version = "1.0.0" +name = "unsigned-varint" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -dependencies = [ - "void", -] +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" [[package]] name = "untrusted" @@ -5046,6 +4937,42 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" +[[package]] +name = "value-bag" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a72e1902dde2bd6441347de2b70b7f5d59bf157c6c62f0c44572607a1d55bbe" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ba39dc791ecb35baad371a3fc04c6eab688c04937d2e0ac6c22b612c0357bf" +dependencies = [ + "erased-serde", + "serde", + "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e06c10810a57bbf45778d023d432a50a1daa7d185991ae06bcfb6c654d0945" +dependencies = [ + "sval", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", +] + [[package]] name = "vcpkg" version = "0.2.15" @@ -5065,10 +4992,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] -name = "void" -version = "1.0.2" +name = "walkdir" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] [[package]] name = "want" @@ -5085,12 +5016,6 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -5192,17 +5117,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "which" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" -dependencies = [ - "either", - "libc", - "once_cell", -] - [[package]] name = "winapi" version = "0.3.9" @@ -5390,15 +5304,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" -[[package]] -name = "winnow" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" -dependencies = [ - "memchr", -] - [[package]] name = "winreg" version = "0.10.1" @@ -5432,7 +5337,16 @@ dependencies = [ "oid-registry", "rusticata-macros", "thiserror", - "time 0.3.22", + "time", +] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", ] [[package]] @@ -5441,7 +5355,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ - "time 0.3.22", + "time", ] [[package]] diff --git a/examples/functions/05_raffle_program/switchboard-function/Cargo.toml b/examples/functions/05_raffle_program/switchboard-function/Cargo.toml index f7e15dc54..7808f35f7 100644 --- a/examples/functions/05_raffle_program/switchboard-function/Cargo.toml +++ b/examples/functions/05_raffle_program/switchboard-function/Cargo.toml @@ -8,6 +8,8 @@ edition = "2021" [dependencies] tokio = "^1" futures = "0.3" -# switchboard-solana = "0.28.19" -switchboard-solana = { version = "0.28.19", path = "../../../../rust/switchboard-solana" } -switchboard-utils = { version = "0.8", path = "../../../../../../rust/switchboard-utils" } +# switchboard-solana = "0.28.43" +switchboard-solana = { path = "../../../../rust/switchboard-solana", features = [ + "macros", +] } +switchboard-utils = { path = "../../../../../../rust/switchboard-utils" } diff --git a/examples/functions/05_raffle_program/switchboard-function/src/main.rs b/examples/functions/05_raffle_program/switchboard-function/src/main.rs index 97465acdf..186b8afcc 100644 --- a/examples/functions/05_raffle_program/switchboard-function/src/main.rs +++ b/examples/functions/05_raffle_program/switchboard-function/src/main.rs @@ -3,18 +3,17 @@ pub use switchboard_solana::prelude::*; pub mod params; pub use params::*; -#[tokio::main(worker_threads = 12)] -async fn main() { - // First, initialize the runner instance with a freshly generated Gramine keypair - let runner = FunctionRunner::new_from_cluster(Cluster::Devnet, None).unwrap(); +#[switchboard_function] +pub async fn raffle_callback( + runner: FunctionRunner, + params: Vec +) -> Result, SbFunctionError> { + // parse and validate user provided request params + let params = ContainerParams::decode(¶ms).unwrap(); // Then, write your own Rust logic and build a Vec of instructions. // Should be under 700 bytes after serialization let ixs: Vec = vec![]; - // TODO: add close_round instruction here to close the raffle round - - // Finally, emit the signed quote and partially signed transaction to the functionRunner oracle - // The functionRunner oracle will use the last outputted word to stdout as the serialized result. This is what gets executed on-chain. - runner.emit(ixs).await.unwrap(); + Ok(ixs) } diff --git a/examples/functions/05_raffle_program/switchboard-function/src/params.rs b/examples/functions/05_raffle_program/switchboard-function/src/params.rs index 252c1e551..70925e29e 100644 --- a/examples/functions/05_raffle_program/switchboard-function/src/params.rs +++ b/examples/functions/05_raffle_program/switchboard-function/src/params.rs @@ -8,7 +8,7 @@ pub struct ContainerParams { } impl ContainerParams { - pub fn decode(container_params: &[u8]) -> std::result::Result { + pub fn decode(container_params: &[u8]) -> Result { let params = String::from_utf8(container_params.to_vec()).unwrap(); let mut program_id: Pubkey = Pubkey::default(); @@ -19,30 +19,30 @@ impl ContainerParams { let pair: Vec<&str> = env_pair.splitn(2, '=').collect(); if pair.len() == 2 { match pair[0] { - "PID" => program_id = Pubkey::from_str(pair[1]).unwrap(), - "RAFFLE" => raffle_key = Pubkey::from_str(pair[1]).unwrap(), - "ROUND_CLOSE_SLOT" => round_close_slot = pair[1].parse::().unwrap(), + "PID" => { + program_id = Pubkey::from_str(pair[1]).unwrap(); + } + "RAFFLE" => { + raffle_key = Pubkey::from_str(pair[1]).unwrap(); + } + "ROUND_CLOSE_SLOT" => { + round_close_slot = pair[1].parse::().unwrap(); + } _ => {} } } } if program_id == Pubkey::default() { - return Err(SwitchboardClientError::CustomMessage( - "PID cannot be undefined".to_string(), - )); + return Err(SbFunctionError::FunctionError(100)); } if raffle_key == Pubkey::default() { - return Err(SwitchboardClientError::CustomMessage( - "RAFFLE cannot be undefined".to_string(), - )); + return Err(SbFunctionError::FunctionError(101)); } if round_close_slot == 0 { - return Err(SwitchboardClientError::CustomMessage( - "ROUND_CLOSE_SLOT must be greater than 0".to_string(), - )); + return Err(SbFunctionError::FunctionError(102)); } Ok(Self { @@ -63,7 +63,7 @@ mod tests { "PID={},RAFFLE={},ROUND_CLOSE_SLOT={}", anchor_spl::token::ID, anchor_spl::token::ID, - 8, + 8 ); let request_params_bytes = request_params_string.into_bytes(); diff --git a/examples/vrf/01_vrf_client/package.json b/examples/vrf/01_vrf_client/package.json index 563bf7aeb..36271cd54 100644 --- a/examples/vrf/01_vrf_client/package.json +++ b/examples/vrf/01_vrf_client/package.json @@ -18,9 +18,9 @@ "@project-serum/borsh": "^0.2.5", "@solana/spl-token": "^0.3.6", "@solana/web3.js": "^1.77.3", - "@switchboard-xyz/common": "^2.3.3", - "@switchboard-xyz/oracle": "latest", - "@switchboard-xyz/solana.js": "^2.5.0", + "@switchboard-xyz/common": "*", + "@switchboard-xyz/oracle": "*", + "@switchboard-xyz/solana.js": "*", "chalk": "^4.1.2", "dotenv": "^16.0.1", "yargs": "^17.5.1" diff --git a/javascript/sbv2-lite/package.json b/javascript/sbv2-lite/package.json index 718ef0a57..484384f53 100644 --- a/javascript/sbv2-lite/package.json +++ b/javascript/sbv2-lite/package.json @@ -1,18 +1,16 @@ { "name": "@switchboard-xyz/sbv2-lite", "version": "0.2.2", - "description": "", "private": false, + "description": "", + "homepage": "https://docs.switchboard.xyz", "repository": { "type": "git", "url": "https://github.com/switchboard-xyz/sbv2-solana", "directory": "javascript/sbv2-lite" }, - "homepage": "https://docs.switchboard.xyz", - "files": [ - "lib", - "src" - ], + "license": "ISC", + "author": "", "exports": { ".": { "import": "./lib/esm/index.js", @@ -22,15 +20,20 @@ "main": "lib/cjs/index.js", "module": "lib/esm/index.js", "types": "lib/cjs/index.d.ts", + "files": [ + "lib", + "src" + ], "scripts": { + "build": "shx rm -rf lib && tsc && tsc -p tsconfig.cjs.json", "docgen": "typedoc --entryPoints src/index.ts --out ../../website/static/api/ts-lite", + "prepublishOnly": "pnpm build && pnpm test", "test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha -r ts-node/register 'tests/**/*.ts'", - "build": "shx rm -rf lib && tsc && tsc -p tsconfig.cjs.json", - "watch": "tsc -p tsconfig.cjs.json --watch", - "prepublishOnly": "pnpm build && pnpm test" + "watch": "tsc -p tsconfig.cjs.json --watch" }, - "author": "", - "license": "ISC", + "pre-commit": [ + "build" + ], "dependencies": { "@coral-xyz/anchor": "^0.28.0", "big.js": "^6.1.1" @@ -48,11 +51,8 @@ "typedoc": "^0.23.8", "typescript": "^5.1.6" }, - "pre-commit": [ - "build" - ], "engines": { - "npm": ">=7.0.0", - "node": ">=16.0.0" + "node": ">=16.0.0", + "npm": ">=7.0.0" } } diff --git a/javascript/solana.js/.gitignore b/javascript/solana.js/.gitignore index aa2f448c1..ab92deee3 100644 --- a/javascript/solana.js/.gitignore +++ b/javascript/solana.js/.gitignore @@ -13,6 +13,9 @@ AggregatorAccount.d.ts generated.cjs generated.js generated.d.ts +runner.cjs +runner.js +runner.d.ts generated/accounts.cjs generated/accounts.js generated/accounts.d.ts diff --git a/javascript/solana.js/esbuild.js b/javascript/solana.js/esbuild.js index 368b6bbd0..4b905b75b 100644 --- a/javascript/solana.js/esbuild.js +++ b/javascript/solana.js/esbuild.js @@ -46,6 +46,7 @@ async function main() { TransactionObject: "TransactionObject", AggregatorAccount: "accounts/AggregatorAccount", generated: "generated/index", + runner: "runner/index", "generated/accounts": "generated/accounts", "generated/instructions": "generated/instructions", "generated/types": "generated/types", diff --git a/javascript/solana.js/idl/attestation-devnet.json b/javascript/solana.js/idl/attestation-devnet.json index 59dd6cb1b..b8ffa1775 100644 --- a/javascript/solana.js/idl/attestation-devnet.json +++ b/javascript/solana.js/idl/attestation-devnet.json @@ -68,11 +68,6 @@ "isMut": true, "isSigner": true }, - { - "name": "state", - "isMut": false, - "isSigner": false - }, { "name": "tokenProgram", "isMut": false, @@ -215,74 +210,6 @@ } ] }, - { - "name": "walletClose", - "accounts": [ - { - "name": "wallet", - "isMut": true, - "isSigner": false - }, - { - "name": "mint", - "isMut": false, - "isSigner": false - }, - { - "name": "authority", - "isMut": false, - "isSigner": false - }, - { - "name": "attestationQueue", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenWallet", - "isMut": true, - "isSigner": false - }, - { - "name": "destinationWallet", - "isMut": true, - "isSigner": false - }, - { - "name": "state", - "isMut": false, - "isSigner": false - }, - { - "name": "solDest", - "isMut": false, - "isSigner": false - }, - { - "name": "escrowDest", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "params", - "type": { - "defined": "WalletCloseParams" - } - } - ] - }, { "name": "verifierInit", "accounts": [ @@ -620,18 +547,18 @@ "isSigner": true }, { - "name": "wallet", + "name": "escrowWallet", "isMut": true, "isSigner": false }, { - "name": "walletAuthority", + "name": "escrowWalletAuthority", "isMut": false, "isSigner": true, "isOptional": true }, { - "name": "tokenWallet", + "name": "escrowTokenWallet", "isMut": true, "isSigner": false }, @@ -1002,6 +929,25 @@ }, { "name": "functionVerify", + "docs": [ + "Verifies a function was executed within an enclave and sets the enclave signer", + "on the function account for downstream instructions to verify.", + "", + "# Errors", + "", + "* `InsufficientQueue` - If the attestation queue has no active verifier oracles", + "* `InvalidQuote` - If the verifier oracle has an invalid or expired quote", + "* `IncorrectMrEnclave` - If the verifiers mr_enclave is not found in the attestation queue's enclave set", + "* `IllegalVerifier` - If the incorrect verifier has responded and the routine is less than 30 seconds stale.", + "", + "* `FunctionNotReady` - If the function status is not Active", + "* `InvalidMrEnclave` - If the measured mr_enclave value is not null", + "* `MrEnclavesEmpty` - If the function has 0 mr_enclaves whitelisted", + "* `IncorrectMrEnclave` - If the measured mr_enclave is not found in the functions enclave set", + "", + "* `IncorrectObservedTime` - If the oracles observed time has drifted by 20 seconds", + "" + ], "accounts": [ { "name": "function", @@ -1093,6 +1039,9 @@ }, { "name": "functionRequestInit", + "docs": [ + "Request Actions" + ], "accounts": [ { "name": "request", @@ -1322,6 +1271,33 @@ }, { "name": "functionRequestVerify", + "docs": [ + "Verifies a function request was executed within an enclave and sets", + "the enclave signer on the request account for downstream instructions to verify.", + "", + "# Errors", + "", + "* `InsufficientQueue` - If the attestation queue has no active verifier oracles", + "* `InvalidQuote` - If the verifier oracle has an invalid or expired quote", + "* `IncorrectMrEnclave` - If the verifiers mr_enclave is not found in the attestation queue's enclave set", + "", + "* `RequestRoundNotActive` - If there is no active round for the request", + "* `FunctionRequestNotReady` - If the request is not active yet", + "* `UserRequestsDisabled` - If the function has disabled routines", + "* `FunctionNotReady` - If the function status is not Active", + "* `InvalidMrEnclave` - If the measured mr_enclave value is not null", + "* `MrEnclavesEmpty` - If the function has 0 mr_enclaves whitelisted", + "* `IncorrectMrEnclave` - If the measured mr_enclave is not found in the functions enclave set", + "", + "* `InvalidRequest` - If the provided params.request_slot does not match the active round request_slot", + "* `IllegalExecuteAttempt` - If the request slot is 0 or greater than the current slot", + "", + "* `InvalidEscrow` - If the function escrow was provided but incorrect.", + "* `MissingFunctionEscrow` - If the function escrow was not provided but required because func.routines_dev_fee > 0", + "* `IncorrectObservedTime` - If the oracles observed time has drifted by 20 seconds", + "* `InvalidParamsHash` If the container params hash is not the same as the routine params hash. Used to mitigate malicous RPCs.", + "" + ], "accounts": [ { "name": "request", @@ -1451,114 +1427,278 @@ } } ] - } - ], - "accounts": [ - { - "name": "AttestationProgramState", - "type": { - "kind": "struct", - "fields": [ - { - "name": "bump", - "type": "u8" - }, - { - "name": "ebuf", - "type": { - "array": [ - "u8", - 2048 - ] - } - } - ] - } }, { - "name": "SwitchboardWallet", - "type": { - "kind": "struct", - "fields": [ - { - "name": "bump", - "type": "u8" - }, - { - "name": "initialized", - "type": "u8" - }, - { - "name": "mint", - "type": "publicKey" - }, - { - "name": "attestationQueue", - "type": "publicKey" - }, - { - "name": "authority", - "type": "publicKey" - }, - { - "name": "name", - "type": { - "array": [ - "u8", - 32 - ] - } - }, - { - "name": "resourceCount", - "type": "u32" - }, - { - "name": "withdrawAuthority", - "type": "publicKey" - }, - { - "name": "tokenWallet", - "type": "publicKey" - }, - { - "name": "resources", - "type": { - "vec": "publicKey" - } - }, - { - "name": "resourcesMaxLen", - "type": "u32" - }, - { - "name": "ebuf", - "docs": [ - "Reserved." - ], - "type": { - "array": [ - "u8", - 64 - ] - } + "name": "functionRoutineInit", + "docs": [ + "Routine Actions", + "Initializes a Function routine account", + "", + "# Errors", + "", + "* `MissingSbWalletAuthoritySigner` - If the provided SbWallet authority does not match the routine", + "authority and the wallet authority did not sign the transaction." + ], + "accounts": [ + { + "name": "routine", + "isMut": true, + "isSigner": true + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "functionAuthority", + "isMut": false, + "isSigner": true, + "isOptional": true + }, + { + "name": "escrowWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "escrowWalletAuthority", + "isMut": false, + "isSigner": true, + "isOptional": true + }, + { + "name": "escrowTokenWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "mint", + "isMut": false, + "isSigner": false + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "associatedTokenProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionRoutineInitParams" } - ] - } + } + ] }, { - "name": "FunctionAccountData", - "type": { - "kind": "struct", - "fields": [ - { - "name": "isScheduled", - "docs": [ - "Whether the function is invoked on a schedule or by request" - ], - "type": "u8" - }, - { + "name": "functionRoutineSetConfig", + "accounts": [ + { + "name": "routine", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionRoutineSetConfigParams" + } + } + ] + }, + { + "name": "functionRoutineDisable", + "accounts": [ + { + "name": "routine", + "isMut": true, + "isSigner": false + }, + { + "name": "function", + "isMut": false, + "isSigner": false + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true, + "isOptional": true + }, + { + "name": "functionAuthority", + "isMut": false, + "isSigner": true, + "isOptional": true + }, + { + "name": "queueAuthority", + "isMut": false, + "isSigner": true, + "isOptional": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionRoutineDisableParams" + } + } + ] + }, + { + "name": "functionRoutineVerify", + "docs": [ + "Verifies a function routine was executed within an enclave and sets", + "the enclave signer on the routine account for downstream instructions to verify.", + "", + "# Errors", + "", + "* `InsufficientQueue` - If the attestation queue has no active verifier oracles", + "* `InvalidQuote` - If the verifier oracle has an invalid or expired quote", + "* `IncorrectMrEnclave` - If the verifiers mr_enclave is not found in the attestation queue's enclave set", + "* `IllegalVerifier` - If the incorrect verifier has responded and the routine is less than 30 seconds stale.", + "", + "* `RoutineDisabled` - If the routine has been disabled", + "* `FunctionRoutinesDisabled` - If the function has disabled routines", + "* `FunctionNotReady` - If the function status is not Active", + "* `InvalidMrEnclave` - If the measured mr_enclave value is not null", + "* `MrEnclavesEmpty` - If the function has 0 mr_enclaves whitelisted", + "* `IncorrectMrEnclave` - If the measured mr_enclave is not found in the functions enclave set", + "", + "* `InvalidEscrow` - If the function escrow was provided but incorrect.", + "* `MissingFunctionEscrow` - If the function escrow was not provided but required because func.routines_dev_fee > 0", + "* `IncorrectObservedTime` - If the oracles observed time has drifted by 20 seconds", + "* `InvalidParamsHash` If the container params hash is not the same as the routine params hash. Used to mitigate malicous RPCs.", + "" + ], + "accounts": [ + { + "name": "routine", + "isMut": true, + "isSigner": false + }, + { + "name": "functionEnclaveSigner", + "isMut": false, + "isSigner": true + }, + { + "name": "escrowWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "escrowTokenWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "functionEscrowTokenWallet", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "verifierQuote", + "isMut": false, + "isSigner": false + }, + { + "name": "verifierEnclaveSigner", + "isMut": false, + "isSigner": true + }, + { + "name": "verifierPermission", + "isMut": false, + "isSigner": false + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "receiver", + "isMut": true, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionRoutineVerifyParams" + } + } + ] + } + ], + "accounts": [ + { + "name": "FunctionAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "isScheduled", + "docs": [ + "Whether the function is invoked on a schedule or by request" + ], + "type": "u8" + }, + { "name": "isTriggered", "docs": [ "Whether the function has been manually triggered with the function_trigger instruction" @@ -1815,7 +1955,7 @@ "docs": [ "Whether custom requests have been disabled for this function." ], - "type": "bool" + "type": "u8" }, { "name": "requestsRequireAuthorization", @@ -1823,7 +1963,7 @@ "Whether new requests need to be authorized by the FunctionAccount authority before being initialized.", "Useful if you want to use CPIs to control request account creation." ], - "type": "bool" + "type": "u8" }, { "name": "reserved1", @@ -1838,16 +1978,18 @@ } }, { - "name": "requestsFee", + "name": "requestsDevFee", "docs": [ - "The lamports paid to the FunctionAccount escrow on each successful update request." + "The dev fee that is paid out from the request's escrow to the function's escrow on each successful invocation.", + "This is used to reward the function maintainer for providing the function.", + "0 = No Fee. Sender = requests's escrow_token_wallet. Receiver = function's reward_token_wallet." ], "type": "u64" }, { "name": "escrowWallet", "docs": [ - "The SwitchboardWallet that will handle pre-funding rewards paid out to function runners." + "The SwitchboardWallet that will handle pre-funding rewards paid out to function verifiers." ], "type": "publicKey" }, @@ -1874,106 +2016,49 @@ "type": "publicKey" }, { - "name": "ebuf", - "docs": [ - "Reserved." - ], - "type": { - "array": [ - "u8", - 1024 - ] - } - } - ] - } - }, - { - "name": "FunctionRequestAccountData", - "type": { - "kind": "struct", - "fields": [ - { - "name": "isTriggered", + "name": "errorStatus", "docs": [ - "Whether the request is ready to be processed." + "The last reported error code if the most recent response was a failure" ], "type": "u8" }, { - "name": "status", - "docs": [ - "The status of the current request." - ], - "type": { - "defined": "RequestStatus" - } - }, - { - "name": "authority", - "docs": [ - "Signer allowed to cancel the request." - ], - "type": "publicKey" - }, - { - "name": "payer", - "docs": [ - "The default destination for rent exemption when the account is closed." - ], - "type": "publicKey" - }, - { - "name": "function", - "docs": [ - "The function that can process this request" - ], - "type": "publicKey" - }, - { - "name": "escrow", - "docs": [ - "The tokenAccount escrow" - ], - "type": "publicKey" - }, - { - "name": "attestationQueue", + "name": "numRoutines", "docs": [ - "The Attestation Queue for this request." + "Number of routines created for this function. Used to prevent closing when there are live routines." ], - "type": "publicKey" + "type": "u64" }, { - "name": "activeRequest", + "name": "routinesDisabled", "docs": [ - "The current active request." + "Whether custom routines have been disabled for this function." ], "type": { - "defined": "FunctionRequestTriggerRound" + "defined": "BoolWithLock" } }, { - "name": "previousRequest", + "name": "routinesRequireAuthorization", "docs": [ - "The previous request." + "Whether new routines need to be authorized by the FunctionAccount authority before being initialized.", + "Useful if you want to provide AccessControl and only allow certain parties to run routines." ], - "type": { - "defined": "FunctionRequestTriggerRound" - } + "type": "u8" }, { - "name": "maxContainerParamsLen", + "name": "routinesDevFee", "docs": [ - "The maximum number of bytes to pass to the container params." + "The fee that is paid out from the routine's escrow to the function's escrow on each successful invocation.", + "This is used to reward the function maintainer for providing the function.", + "0 = No Fee. Sender = routine's escrow_token_wallet. Receiver = function's reward_token_wallet." ], - "type": "u32" + "type": "u64" }, { - "name": "containerParamsHash", + "name": "mrEnclave", "docs": [ - "Hash of the serialized container_params to prevent RPC tampering.", - "Should be verified within your function to ensure you are using the correct parameters." + "The functions MRENCLAVE measurement dictating the contents of the secure enclave." ], "type": { "array": [ @@ -1983,27 +2068,25 @@ } }, { - "name": "containerParams", + "name": "verificationStatus", "docs": [ - "The stringified container params to pass to the function." + "The VerificationStatus of the quote." ], - "type": "bytes" + "type": "u8" }, { - "name": "createdAt", + "name": "verificationTimestamp", "docs": [ - "The unix timestamp when the function was created." + "The unix timestamp when the quote was last verified." ], "type": "i64" }, { - "name": "garbageCollectionSlot", + "name": "validUntil", "docs": [ - "The slot when the account can be garbage collected and closed by anyone for a portion of the rent." + "The unix timestamp when the quotes verification status expires." ], - "type": { - "option": "u64" - } + "type": "i64" }, { "name": "ebuf", @@ -2013,7 +2096,7 @@ "type": { "array": [ "u8", - 256 + 956 ] } } @@ -2021,14 +2104,595 @@ } }, { - "name": "VerifierAccountData", + "name": "AttestationPermissionAccountData", "type": { "kind": "struct", "fields": [ { - "name": "enclave", - "docs": [ - "Represents the state of the quote verifiers enclave." + "name": "authority", + "type": "publicKey" + }, + { + "name": "permissions", + "type": "u32" + }, + { + "name": "granter", + "type": "publicKey" + }, + { + "name": "grantee", + "type": "publicKey" + }, + { + "name": "expiration", + "type": "i64" + }, + { + "name": "bump", + "type": "u8" + }, + { + "name": "ebuf", + "type": { + "array": [ + "u8", + 256 + ] + } + } + ] + } + }, + { + "name": "AttestationQueueAccountData", + "docs": [ + "An AttestationQueue represents a round-robin queue of verifier oracles who attest on-chain", + "whether a Switchboard Function was executed within an enclave against an expected set of", + "enclave measurements.", + "", + "For an oracle to join the queue, the oracle must first submit their enclave quote on-chain and", + "wait for an existing verifier to attest their quote. If the oracle's quote matches an expected", + "measurement within the queues mr_enclaves config, it is granted permissions and will start", + "being assigned update requests." + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "authority", + "docs": [ + "The address of the authority which is permitted to add/remove allowed enclave measurements." + ], + "type": "publicKey" + }, + { + "name": "mrEnclaves", + "docs": [ + "Allowed enclave measurements." + ], + "type": { + "array": [ + { + "array": [ + "u8", + 32 + ] + }, + 32 + ] + } + }, + { + "name": "mrEnclavesLen", + "docs": [ + "The number of allowed enclave measurements." + ], + "type": "u32" + }, + { + "name": "data", + "docs": [ + "The addresses of the quote verifiers who have a valid", + "verification status and have heartbeated on-chain recently." + ], + "type": { + "array": [ + "publicKey", + 128 + ] + } + }, + { + "name": "dataLen", + "docs": [ + "The length of valid quote verifiers for the given attestation queue." + ], + "type": "u32" + }, + { + "name": "allowAuthorityOverrideAfter", + "docs": [ + "Allow authority to force add a node after X seconds with no heartbeat." + ], + "type": "i64" + }, + { + "name": "requireAuthorityHeartbeatPermission", + "docs": [ + "Even if a heartbeating machine quote verifies with proper measurement,", + "require authority signoff." + ], + "type": "bool" + }, + { + "name": "requireUsagePermissions", + "docs": [ + "Require FunctionAccounts to have PermitQueueUsage before they are executed." + ], + "type": "bool" + }, + { + "name": "maxQuoteVerificationAge", + "docs": [ + "The maximum allowable time until a EnclaveAccount needs to be re-verified on-chain." + ], + "type": "i64" + }, + { + "name": "reward", + "docs": [ + "The reward paid to quote verifiers for attesting on-chain." + ], + "type": "u32" + }, + { + "name": "lastHeartbeat", + "docs": [ + "The unix timestamp when the last quote verifier heartbeated on-chain." + ], + "type": "i64" + }, + { + "name": "nodeTimeout", + "type": "i64" + }, + { + "name": "currIdx", + "docs": [ + "Incrementer used to track the current quote verifier permitted to run any available functions." + ], + "type": "u32" + }, + { + "name": "gcIdx", + "docs": [ + "Incrementer used to garbage collect and remove stale quote verifiers." + ], + "type": "u32" + }, + { + "name": "verifierMinStake", + "docs": [ + "The minimum number of lamports a quote verifier needs to lock-up in order to heartbeat and verify other quotes." + ], + "type": "u64" + }, + { + "name": "functionMinStake", + "docs": [ + "The minimum number of lamports a function needs to lock-up in order to use a queues resources." + ], + "type": "u64" + }, + { + "name": "ebuf", + "docs": [ + "Reserved." + ], + "type": { + "array": [ + "u8", + 1008 + ] + } + } + ] + } + }, + { + "name": "FunctionRequestAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "isTriggered", + "docs": [ + "Whether the request is ready to be processed." + ], + "type": "u8" + }, + { + "name": "status", + "docs": [ + "The status of the current request." + ], + "type": { + "defined": "RequestStatus" + } + }, + { + "name": "authority", + "docs": [ + "Signer allowed to cancel the request." + ], + "type": "publicKey" + }, + { + "name": "payer", + "docs": [ + "The default destination for rent exemption when the account is closed." + ], + "type": "publicKey" + }, + { + "name": "function", + "docs": [ + "The function that can process this request" + ], + "type": "publicKey" + }, + { + "name": "escrow", + "docs": [ + "The tokenAccount escrow" + ], + "type": "publicKey" + }, + { + "name": "attestationQueue", + "docs": [ + "The Attestation Queue for this request." + ], + "type": "publicKey" + }, + { + "name": "activeRequest", + "docs": [ + "The current active request." + ], + "type": { + "defined": "FunctionRequestTriggerRound" + } + }, + { + "name": "previousRequest", + "docs": [ + "The previous request." + ], + "type": { + "defined": "FunctionRequestTriggerRound" + } + }, + { + "name": "maxContainerParamsLen", + "docs": [ + "The maximum number of bytes to pass to the container params." + ], + "type": "u32" + }, + { + "name": "containerParamsHash", + "docs": [ + "Hash of the serialized container_params to prevent RPC tampering.", + "Should be verified within your function to ensure you are using the correct parameters." + ], + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "containerParams", + "docs": [ + "The stringified container params to pass to the function." + ], + "type": "bytes" + }, + { + "name": "createdAt", + "docs": [ + "The unix timestamp when the function was created." + ], + "type": "i64" + }, + { + "name": "garbageCollectionSlot", + "docs": [ + "The slot when the account can be garbage collected and closed by anyone for a portion of the rent." + ], + "type": { + "option": "u64" + } + }, + { + "name": "errorStatus", + "docs": [ + "The last recorded error code if most recent response was an error." + ], + "type": "u8" + }, + { + "name": "ebuf", + "docs": [ + "Reserved." + ], + "type": { + "array": [ + "u8", + 255 + ] + } + } + ] + } + }, + { + "name": "FunctionRoutineAccountData", + "docs": [ + "The function routine account provides scheduled execution of Switchboard Functions", + "with a configurable cron-based schedule and container parameters.", + "", + "Function routines maintain their own queue_idx to provide round-robin assignment of", + "verifiers for each settled execution. This is incremented after each invocation.", + "", + "Function routines can share a SwitchboardWallet as long as the escrow authority has", + "signed the transaction." + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "docs": [ + "The name of the function routine for easier identification." + ], + "type": { + "array": [ + "u8", + 64 + ] + } + }, + { + "name": "metadata", + "docs": [ + "The metadata of the function routine for easier identification." + ], + "type": { + "array": [ + "u8", + 256 + ] + } + }, + { + "name": "createdAt", + "docs": [ + "The unix timestamp when the function routine was created." + ], + "type": "i64" + }, + { + "name": "updatedAt", + "docs": [ + "The unix timestamp when the function routine config was changed." + ], + "type": "i64" + }, + { + "name": "isDisabled", + "docs": [ + "Flag to disable the function and prevent new verification requests." + ], + "type": { + "defined": "ResourceLevel" + } + }, + { + "name": "status", + "docs": [ + "The type of resource that disabled the routine." + ], + "type": { + "defined": "RoutineStatus" + } + }, + { + "name": "errorStatus", + "docs": [ + "The last reported error code if the most recent response was a failure" + ], + "type": "u8" + }, + { + "name": "enclaveSigner", + "docs": [ + "The enclave generated signer for this routine." + ], + "type": "publicKey" + }, + { + "name": "verifier", + "docs": [ + "The verifier oracle who signed this verification." + ], + "type": "publicKey" + }, + { + "name": "bounty", + "docs": [ + "The SOL bounty in lamports used to incentivize a verifier to expedite the request. 0 = no bounty. Receiver = verifier oracle." + ], + "type": "u64" + }, + { + "name": "authority", + "docs": [ + "Signer allowed to manage the routine." + ], + "type": "publicKey" + }, + { + "name": "payer", + "docs": [ + "The default destination for rent exemption when the account is closed." + ], + "type": "publicKey" + }, + { + "name": "function", + "docs": [ + "The function that manages the mr_enclave set for this routine." + ], + "type": "publicKey" + }, + { + "name": "attestationQueue", + "docs": [ + "The Attestation Queue for this request." + ], + "type": "publicKey" + }, + { + "name": "escrowWallet", + "docs": [ + "The tokenAccount escrow" + ], + "type": "publicKey" + }, + { + "name": "escrowTokenWallet", + "docs": [ + "The TokenAccount with funds for the escrow." + ], + "type": "publicKey" + }, + { + "name": "queueIdx", + "docs": [ + "The index of the verifier on the queue that is assigned to process the next invocation.", + "This is incremented after each invocation in a round-robin fashion." + ], + "type": "u32" + }, + { + "name": "schedule", + "docs": [ + "The cron schedule to run the function on." + ], + "type": { + "array": [ + "u8", + 64 + ] + } + }, + { + "name": "maxContainerParamsLen", + "docs": [ + "The maximum number of bytes to pass to the container params." + ], + "type": "u32" + }, + { + "name": "containerParamsHash", + "docs": [ + "Hash of the serialized container_params to prevent RPC tampering.", + "Should be verified within your function to ensure you are using the correct parameters." + ], + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "containerParams", + "docs": [ + "The stringified container params to pass to the function." + ], + "type": "bytes" + }, + { + "name": "lastExecutionTimestamp", + "docs": [ + "The unix timestamp when the function was last run." + ], + "type": "i64" + }, + { + "name": "lastSuccessfulExecutionTimestamp", + "docs": [ + "The unix timestamp when the function was last run successfully." + ], + "type": "i64" + }, + { + "name": "nextAllowedTimestamp", + "docs": [ + "The unix timestamp when the function is allowed to run next." + ], + "type": "i64" + }, + { + "name": "ebuf", + "docs": [ + "Reserved." + ], + "type": { + "array": [ + "u8", + 512 + ] + } + } + ] + } + }, + { + "name": "AttestationProgramState", + "type": { + "kind": "struct", + "fields": [ + { + "name": "bump", + "type": "u8" + }, + { + "name": "ebuf", + "type": { + "array": [ + "u8", + 2048 + ] + } + } + ] + } + }, + { + "name": "VerifierAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "enclave", + "docs": [ + "Represents the state of the quote verifiers enclave." ], "type": { "defined": "Quote" @@ -2060,7 +2724,7 @@ "docs": [ "Whether the quote is located on the AttestationQueues buffer." ], - "type": "bool" + "type": "u8" }, { "name": "lastHeartbeat", @@ -2101,186 +2765,98 @@ } }, { - "name": "AttestationQueueAccountData", + "name": "SwitchboardWallet", "type": { "kind": "struct", "fields": [ { - "name": "authority", - "docs": [ - "The address of the authority which is permitted to add/remove allowed enclave measurements." - ], - "type": "publicKey" - }, - { - "name": "mrEnclaves", - "docs": [ - "Allowed enclave measurements." - ], - "type": { - "array": [ - { - "array": [ - "u8", - 32 - ] - }, - 32 - ] - } - }, - { - "name": "mrEnclavesLen", - "docs": [ - "The number of allowed enclave measurements." - ], - "type": "u32" - }, - { - "name": "data", - "docs": [ - "The addresses of the quote verifiers who have a valid", - "verification status and have heartbeated on-chain recently." - ], - "type": { - "array": [ - "publicKey", - 128 - ] - } - }, - { - "name": "dataLen", - "docs": [ - "The length of valid quote verifiers for the given attestation queue." - ], - "type": "u32" - }, - { - "name": "allowAuthorityOverrideAfter", - "docs": [ - "Allow authority to force add a node after X seconds with no heartbeat." - ], - "type": "i64" - }, - { - "name": "requireAuthorityHeartbeatPermission", + "name": "bump", "docs": [ - "Even if a heartbeating machine quote verifies with proper measurement,", - "require authority signoff." + "The bump used to derive the PDA." ], - "type": "bool" + "type": "u8" }, { - "name": "requireUsagePermissions", + "name": "initialized", "docs": [ - "Require FunctionAccounts to have PermitQueueUsage before they are executed." + "Flag dictating whether the wallet has been initialized already." ], - "type": "bool" + "type": "u8" }, { - "name": "maxQuoteVerificationAge", + "name": "mint", "docs": [ - "The maximum allowable time until a EnclaveAccount needs to be re-verified on-chain." + "The public key of the mint used for this wallet." ], - "type": "i64" + "type": "publicKey" }, { - "name": "reward", + "name": "attestationQueue", "docs": [ - "The reward paid to quote verifiers for attesting on-chain." + "The attestation queue pubkey." ], - "type": "u32" + "type": "publicKey" }, { - "name": "lastHeartbeat", + "name": "authority", "docs": [ - "The unix timestamp when the last quote verifier heartbeated on-chain." + "The wallet authority that is permitted to make account changes." ], - "type": "i64" - }, - { - "name": "nodeTimeout", - "type": "i64" + "type": "publicKey" }, { - "name": "currIdx", + "name": "name", "docs": [ - "Incrementer used to track the current quote verifier permitted to run any available functions." + "The name of the wallet for easier identification." ], - "type": "u32" + "type": { + "array": [ + "u8", + 32 + ] + } }, { - "name": "gcIdx", + "name": "resourceCount", "docs": [ - "Incrementer used to garbage collect and remove stale quote verifiers." + "The number of resources tied to this wallet." ], "type": "u32" }, { - "name": "verifierMinStake", + "name": "withdrawAuthority", "docs": [ - "The minimum number of lamports a quote verifier needs to lock-up in order to heartbeat and verify other quotes." + "The pubkey of the account that is permitted to withdraw funds from the wallet.", + "Setting this to the default pubkey will lock deposited funds." ], - "type": "u64" + "type": "publicKey" }, { - "name": "functionMinStake", + "name": "tokenWallet", "docs": [ - "The minimum number of lamports a function needs to lock-up in order to use a queues resources." + "The associated token account pubkey." ], - "type": "u64" + "type": "publicKey" }, { - "name": "ebuf", - "docs": [ - "Reserved." - ], + "name": "resources", "type": { - "array": [ - "u8", - 1008 - ] + "vec": "publicKey" } - } - ] - } - }, - { - "name": "AttestationPermissionAccountData", - "type": { - "kind": "struct", - "fields": [ - { - "name": "authority", - "type": "publicKey" }, { - "name": "permissions", + "name": "resourcesMaxLen", "type": "u32" }, - { - "name": "granter", - "type": "publicKey" - }, - { - "name": "grantee", - "type": "publicKey" - }, - { - "name": "expiration", - "type": "i64" - }, - { - "name": "bump", - "type": "u8" - }, { "name": "ebuf", + "docs": [ + "Reserved." + ], "type": { "array": [ "u8", - 256 + 64 ] } } @@ -2315,6 +2891,21 @@ "type": { "kind": "struct", "fields": [ + { + "name": "recentSlot", + "type": "u64" + }, + { + "name": "creatorSeed", + "type": { + "option": { + "array": [ + "u8", + 32 + ] + } + } + }, { "name": "name", "type": "bytes" @@ -2335,23 +2926,17 @@ "name": "version", "type": "bytes" }, - { - "name": "schedule", - "type": "bytes" - }, { "name": "mrEnclave", "type": { - "array": [ - "u8", - 32 - ] + "option": { + "array": [ + "u8", + 32 + ] + } } }, - { - "name": "recentSlot", - "type": "u64" - }, { "name": "requestsDisabled", "type": "bool" @@ -2361,19 +2946,20 @@ "type": "bool" }, { - "name": "requestsFee", + "name": "requestsDevFee", "type": "u64" }, { - "name": "creatorSeed", - "type": { - "option": { - "array": [ - "u8", - 32 - ] - } - } + "name": "routinesDisabled", + "type": "bool" + }, + { + "name": "routinesRequireAuthorization", + "type": "bool" + }, + { + "name": "routinesDevFee", + "type": "u64" } ] } @@ -2428,38 +3014,56 @@ } }, { - "name": "schedule", + "name": "mrEnclaves", + "type": { + "option": { + "vec": { + "array": [ + "u8", + 32 + ] + } + } + } + }, + { + "name": "requestsDisabled", + "type": { + "option": "bool" + } + }, + { + "name": "requestsRequireAuthorization", + "type": { + "option": "bool" + } + }, + { + "name": "requestsDevFee", "type": { - "option": "bytes" + "option": "u64" } }, { - "name": "mrEnclaves", + "name": "routinesDisabled", "type": { - "option": { - "vec": { - "array": [ - "u8", - 32 - ] - } - } + "option": "bool" } }, { - "name": "requestsDisabled", + "name": "lockRoutinesDisabled", "type": { "option": "bool" } }, { - "name": "requestsRequireAuthorization", + "name": "routinesRequireAuthorization", "type": { "option": "bool" } }, { - "name": "requestsFee", + "name": "routinesDevFee", "type": { "option": "u64" } @@ -2495,8 +3099,8 @@ "type": "i64" }, { - "name": "isFailure", - "type": "bool" + "name": "errorCode", + "type": "u8" }, { "name": "mrEnclave", @@ -2726,8 +3330,8 @@ "type": "i64" }, { - "name": "isFailure", - "type": "bool" + "name": "errorCode", + "type": "u8" }, { "name": "mrEnclave", @@ -2754,6 +3358,140 @@ ] } }, + { + "name": "FunctionRoutineDisableParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "enable", + "type": { + "option": "bool" + } + } + ] + } + }, + { + "name": "FunctionRoutineInitParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "type": { + "option": "bytes" + } + }, + { + "name": "metadata", + "type": { + "option": "bytes" + } + }, + { + "name": "bounty", + "type": { + "option": "u64" + } + }, + { + "name": "schedule", + "type": "bytes" + }, + { + "name": "maxContainerParamsLen", + "type": { + "option": "u32" + } + }, + { + "name": "containerParams", + "type": "bytes" + } + ] + } + }, + { + "name": "FunctionRoutineSetConfigParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "type": { + "option": "bytes" + } + }, + { + "name": "metadata", + "type": { + "option": "bytes" + } + }, + { + "name": "bounty", + "type": { + "option": "u64" + } + }, + { + "name": "schedule", + "type": { + "option": "bytes" + } + }, + { + "name": "containerParams", + "type": { + "option": "bytes" + } + }, + { + "name": "appendContainerParams", + "type": "bool" + } + ] + } + }, + { + "name": "FunctionRoutineVerifyParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "observedTime", + "type": "i64" + }, + { + "name": "nextAllowedTimestamp", + "type": "i64" + }, + { + "name": "errorCode", + "type": "u8" + }, + { + "name": "mrEnclave", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "containerParamsHash", + "type": { + "array": [ + "u8", + 32 + ] + } + } + ] + } + }, { "name": "StateInitParams", "type": { @@ -2852,12 +3590,6 @@ { "name": "name", "type": "bytes" - }, - { - "name": "maxLen", - "type": { - "option": "u32" - } } ] } @@ -2875,68 +3607,73 @@ } }, { - "name": "FunctionRequestTriggerRound", + "name": "Quote", "type": { "kind": "struct", "fields": [ { - "name": "status", - "docs": [ - "The status of the request." - ], - "type": { - "defined": "RequestStatus" - } - }, - { - "name": "bounty", + "name": "enclaveSigner", "docs": [ - "The SOL bounty in lamports used to incentivize a verifier to expedite the request." + "The address of the signer generated within an enclave." ], - "type": "u64" + "type": "publicKey" }, { - "name": "requestSlot", + "name": "mrEnclave", "docs": [ - "The slot the request was published" + "The quotes MRENCLAVE measurement dictating the contents of the secure enclave." ], - "type": "u64" + "type": { + "array": [ + "u8", + 32 + ] + } }, { - "name": "fulfilledSlot", + "name": "verificationStatus", "docs": [ - "The slot when the request was fulfilled" + "The VerificationStatus of the quote." ], - "type": "u64" + "type": "u8" }, { - "name": "expirationSlot", + "name": "verificationTimestamp", "docs": [ - "The slot when the request will expire and be able to be closed by the non-authority account" + "The unix timestamp when the quote was last verified." ], - "type": "u64" + "type": "i64" }, { - "name": "verifier", + "name": "validUntil", "docs": [ - "The EnclaveAccount who verified the enclave for this request" + "The unix timestamp when the quotes verification status expires." ], - "type": "publicKey" + "type": "i64" }, { - "name": "enclaveSigner", + "name": "quoteRegistry", "docs": [ - "The keypair generated in the enclave and required to sign any", - "valid transactions processed by the function." + "The off-chain registry where the verifiers quote can be located." ], - "type": "publicKey" + "type": { + "array": [ + "u8", + 32 + ] + } }, { - "name": "validAfterSlot", + "name": "registryKey", "docs": [ - "The slot when the request can first be executed." + "Key to lookup the buffer data on IPFS or an alternative decentralized storage solution." ], - "type": "u64" + "type": { + "array": [ + "u8", + 64 + ] + } }, { "name": "ebuf", @@ -2946,7 +3683,7 @@ "type": { "array": [ "u8", - 56 + 256 ] } } @@ -2954,73 +3691,72 @@ } }, { - "name": "Quote", + "name": "FunctionRequestTriggerRound", "type": { "kind": "struct", "fields": [ { - "name": "enclaveSigner", + "name": "status", "docs": [ - "The address of the signer generated within an enclave." + "The status of the request." ], - "type": "publicKey" + "type": { + "defined": "RequestStatus" + } }, { - "name": "mrEnclave", + "name": "bounty", "docs": [ - "The quotes MRENCLAVE measurement dictating the contents of the secure enclave." + "The SOL bounty in lamports used to incentivize a verifier to expedite the request." ], - "type": { - "array": [ - "u8", - 32 - ] - } + "type": "u64" }, { - "name": "verificationStatus", + "name": "requestSlot", "docs": [ - "The VerificationStatus of the quote." + "The slot the request was published" ], - "type": "u8" + "type": "u64" + }, + { + "name": "fulfilledSlot", + "docs": [ + "The slot when the request was fulfilled" + ], + "type": "u64" }, { - "name": "verificationTimestamp", + "name": "expirationSlot", "docs": [ - "The unix timestamp when the quote was last verified." + "The slot when the request will expire and be able to be closed by the non-authority account" ], - "type": "i64" + "type": "u64" }, { - "name": "validUntil", + "name": "verifier", "docs": [ - "The unix timestamp when the quotes verification status expires." + "The EnclaveAccount who verified the enclave for this request" ], - "type": "i64" + "type": "publicKey" }, { - "name": "quoteRegistry", + "name": "enclaveSigner", "docs": [ - "The off-chain registry where the verifiers quote can be located." + "The keypair generated in the enclave and required to sign any", + "valid transactions processed by the function." ], - "type": { - "array": [ - "u8", - 32 - ] - } + "type": "publicKey" }, { - "name": "registryKey", + "name": "validAfterSlot", "docs": [ - "Key to lookup the buffer data on IPFS or an alternative decentralized storage solution." + "The slot when the request can first be executed." ], - "type": { - "array": [ - "u8", - 64 - ] - } + "type": "u64" + }, + { + "name": "queueIdx", + "type": "u32" }, { "name": "ebuf", @@ -3030,13 +3766,78 @@ "type": { "array": [ "u8", - 256 + 52 ] } } ] } }, + { + "name": "BoolWithLock", + "docs": [ + "An enum representing a boolean flag which can be locked.", + "Byte #0: 0 = Disabled, 1 = Enabled", + "Byte #1: 0 = Unlocked, 1 = Locked" + ], + "type": { + "kind": "enum", + "variants": [ + { + "name": "Disabled" + }, + { + "name": "Enabled" + }, + { + "name": "DisabledLocked" + }, + { + "name": "EnabledLocked" + } + ] + } + }, + { + "name": "ResourceLevel", + "docs": [ + "An enum representing a heirarchy of resources that can modify a field." + ], + "type": { + "kind": "enum", + "variants": [ + { + "name": "None" + }, + { + "name": "Authority" + }, + { + "name": "Function" + }, + { + "name": "Queue" + } + ] + } + }, + { + "name": "RoutineStatus", + "type": { + "kind": "enum", + "variants": [ + { + "name": "None" + }, + { + "name": "Active" + }, + { + "name": "NonExecutable" + } + ] + } + }, { "name": "FunctionStatus", "type": { @@ -3052,7 +3853,7 @@ "name": "NonExecutable" }, { - "name": "None3" + "name": "Error" }, { "name": "Expired" @@ -3310,6 +4111,46 @@ } ] }, + { + "name": "FunctionRequestVerifyErrorEvent", + "fields": [ + { + "name": "request", + "type": "publicKey", + "index": false + }, + { + "name": "function", + "type": "publicKey", + "index": false + }, + { + "name": "verifier", + "type": "publicKey", + "index": false + }, + { + "name": "containerRegistry", + "type": "bytes", + "index": false + }, + { + "name": "container", + "type": "bytes", + "index": false + }, + { + "name": "params", + "type": "bytes", + "index": false + }, + { + "name": "errorCode", + "type": "u8", + "index": false + } + ] + }, { "name": "FunctionRequestCloseEvent", "fields": [ @@ -3325,6 +4166,121 @@ } ] }, + { + "name": "FunctionRoutineInitEvent", + "fields": [ + { + "name": "attestationQueue", + "type": "publicKey", + "index": false + }, + { + "name": "function", + "type": "publicKey", + "index": false + }, + { + "name": "routine", + "type": "publicKey", + "index": false + }, + { + "name": "schedule", + "type": { + "array": [ + "u8", + 64 + ] + }, + "index": false + } + ] + }, + { + "name": "FunctionRoutineVerifyEvent", + "fields": [ + { + "name": "routine", + "type": "publicKey", + "index": false + }, + { + "name": "function", + "type": "publicKey", + "index": false + }, + { + "name": "verifier", + "type": "publicKey", + "index": false + }, + { + "name": "mrEnclave", + "type": "bytes", + "index": false + }, + { + "name": "containerRegistry", + "type": "bytes", + "index": false + }, + { + "name": "container", + "type": "bytes", + "index": false + }, + { + "name": "params", + "type": "bytes", + "index": false + } + ] + }, + { + "name": "FunctionRoutineVerifyErrorEvent", + "fields": [ + { + "name": "routine", + "type": "publicKey", + "index": false + }, + { + "name": "function", + "type": "publicKey", + "index": false + }, + { + "name": "verifier", + "type": "publicKey", + "index": false + }, + { + "name": "mrEnclave", + "type": "bytes", + "index": false + }, + { + "name": "containerRegistry", + "type": "bytes", + "index": false + }, + { + "name": "container", + "type": "bytes", + "index": false + }, + { + "name": "params", + "type": "bytes", + "index": false + }, + { + "name": "errorCode", + "type": "u8", + "index": false + } + ] + }, { "name": "FunctionTriggerEvent", "fields": [ @@ -3634,7 +4590,8 @@ }, { "code": 6004, - "name": "InsufficientQueue" + "name": "InsufficientQueue", + "msg": "The provided queue is empty and has no verifier oracles heartbeating on-chain." }, { "code": 6005, @@ -3697,7 +4654,8 @@ }, { "code": 6018, - "name": "IncorrectObservedTime" + "name": "IncorrectObservedTime", + "msg": "The provided timestamp is not within the expected range. This may be indicative of an unhealthy enclave." }, { "code": 6019, @@ -3713,7 +4671,8 @@ }, { "code": 6022, - "name": "IncorrectMrEnclave" + "name": "IncorrectMrEnclave", + "msg": "The provided mr_enclave measurement did not match a value in its enclave settings. If you recently modified your function container, you may need to update the measurement in your FunctionAccount config." }, { "code": 6023, @@ -3749,7 +4708,7 @@ { "code": 6030, "name": "RequestExpired", - "msg": "The requests expirationSlot has expired" + "msg": "The requests expiration_slot has expired" }, { "code": 6031, @@ -3803,6 +4762,59 @@ "code": 6041, "name": "FunctionRequestNotReady", "msg": "The FunctionRequestAccount is not ready to be verified" + }, + { + "code": 6042, + "name": "InvalidParamsHash", + "msg": "The container params hash does not match the expected hash on-chain. The parameters may have been modified in-flight; the assigned oracle may need to pickup the account change before re-verifying the function." + }, + { + "code": 6043, + "name": "RequestInvalidStatus" + }, + { + "code": 6044, + "name": "ContainerParamsTooLong", + "msg": "Please ensure your parameters length is <= your account max length" + }, + { + "code": 6045, + "name": "RoutineDisabled", + "msg": "The routine has been disabled. Please check the routin's is_disabled status for more information." + }, + { + "code": 6046, + "name": "FunctionRoutinesDisabled", + "msg": "The function authority has disabled routine execution for this function" + }, + { + "code": 6047, + "name": "ConfigParameterLocked", + "msg": "The configuration parameter has been locked and cannot be changed" + }, + { + "code": 6048, + "name": "RequestBufferFull" + }, + { + "code": 6049, + "name": "RequestRoundNotActive", + "msg": "The request does not have an active round to verify" + }, + { + "code": 6050, + "name": "EmptyEscrow", + "msg": "The resources escrow token account has a balance of 0 and the queue reward is greater than 0" + }, + { + "code": 6051, + "name": "MissingSbWalletAuthoritySigner", + "msg": "The SwitchboardWallet authority must sign this request in order to use its escrow wallet" + }, + { + "code": 6052, + "name": "RequestRoundAlreadyClosed", + "msg": "The verifier is attempting to respond to an already closed request round with the same request_slot" } ] } \ No newline at end of file diff --git a/javascript/solana.js/idl/attestation-mainnet.json b/javascript/solana.js/idl/attestation-mainnet.json new file mode 100644 index 000000000..653b1fc14 --- /dev/null +++ b/javascript/solana.js/idl/attestation-mainnet.json @@ -0,0 +1,3808 @@ +{ + "version": "0.1.0", + "name": "switchboard_attestation_program", + "instructions": [ + { + "name": "viewVersion", + "accounts": [], + "args": [] + }, + { + "name": "stateInit", + "accounts": [ + { + "name": "state", + "isMut": true, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "StateInitParams" + } + } + ] + }, + { + "name": "walletInit", + "accounts": [ + { + "name": "wallet", + "isMut": true, + "isSigner": false + }, + { + "name": "mint", + "isMut": false, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "state", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "associatedTokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "WalletInitParams" + } + } + ] + }, + { + "name": "walletFund", + "accounts": [ + { + "name": "wallet", + "isMut": true, + "isSigner": false + }, + { + "name": "mint", + "isMut": false, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "funderWallet", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "funder", + "isMut": false, + "isSigner": true + }, + { + "name": "state", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "WalletFundParams" + } + } + ] + }, + { + "name": "walletWithdraw", + "accounts": [ + { + "name": "wallet", + "isMut": true, + "isSigner": false + }, + { + "name": "mint", + "isMut": false, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "destinationWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "state", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "WalletWithdrawParams" + } + } + ] + }, + { + "name": "walletClose", + "accounts": [ + { + "name": "wallet", + "isMut": true, + "isSigner": false + }, + { + "name": "mint", + "isMut": false, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "destinationWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "state", + "isMut": false, + "isSigner": false + }, + { + "name": "solDest", + "isMut": false, + "isSigner": false + }, + { + "name": "escrowDest", + "isMut": true, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "WalletCloseParams" + } + } + ] + }, + { + "name": "verifierInit", + "accounts": [ + { + "name": "verifier", + "isMut": true, + "isSigner": true + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "queueAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "VerifierInitParams" + } + } + ] + }, + { + "name": "verifierQuoteRotate", + "accounts": [ + { + "name": "verifier", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "enclaveSigner", + "isMut": false, + "isSigner": false + }, + { + "name": "attestationQueue", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "VerifierQuoteRotateParams" + } + } + ] + }, + { + "name": "verifierQuoteVerify", + "accounts": [ + { + "name": "quote", + "isMut": true, + "isSigner": false + }, + { + "name": "verifier", + "isMut": false, + "isSigner": false + }, + { + "name": "enclaveSigner", + "isMut": false, + "isSigner": true + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "VerifierQuoteVerifyParams" + } + } + ] + }, + { + "name": "verifierHeartbeat", + "accounts": [ + { + "name": "verifier", + "isMut": true, + "isSigner": false + }, + { + "name": "verifierSigner", + "isMut": false, + "isSigner": true + }, + { + "name": "attestationQueue", + "isMut": true, + "isSigner": false + }, + { + "name": "queueAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "gcNode", + "isMut": true, + "isSigner": false + }, + { + "name": "permission", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "VerifierHeartbeatParams" + } + } + ] + }, + { + "name": "attestationQueueInit", + "accounts": [ + { + "name": "queue", + "isMut": true, + "isSigner": true + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AttestationQueueInitParams" + } + } + ] + }, + { + "name": "attestationQueueAddMrEnclave", + "accounts": [ + { + "name": "queue", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AttestationQueueAddMrEnclaveParams" + } + } + ] + }, + { + "name": "attestationQueueRemoveMrEnclave", + "accounts": [ + { + "name": "queue", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AttestationQueueRemoveMrEnclaveParams" + } + } + ] + }, + { + "name": "attestationPermissionInit", + "accounts": [ + { + "name": "permission", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "node", + "isMut": false, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AttestationPermissionInitParams" + } + } + ] + }, + { + "name": "attestationPermissionSet", + "accounts": [ + { + "name": "permission", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "grantee", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AttestationPermissionSetParams" + } + } + ] + }, + { + "name": "functionInit", + "accounts": [ + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "addressLookupTable", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "wallet", + "isMut": true, + "isSigner": false + }, + { + "name": "walletAuthority", + "isMut": false, + "isSigner": true, + "isOptional": true + }, + { + "name": "tokenWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "mint", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "associatedTokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "addressLookupProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionInitParams" + } + } + ] + }, + { + "name": "functionClose", + "accounts": [ + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "addressLookupTable", + "isMut": true, + "isSigner": false + }, + { + "name": "escrowWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "solDest", + "isMut": false, + "isSigner": false + }, + { + "name": "escrowDest", + "isMut": true, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "addressLookupProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionCloseParams" + } + } + ] + }, + { + "name": "functionSetConfig", + "accounts": [ + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionSetConfigParams" + } + } + ] + }, + { + "name": "functionSetAuthority", + "accounts": [ + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "escrowWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "escrowAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "newAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "walletAuthority", + "isMut": false, + "isSigner": true, + "isOptional": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionSetAuthorityParams" + } + } + ] + }, + { + "name": "functionSetEscrow", + "accounts": [ + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "escrowWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "escrowAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "newEscrow", + "isMut": true, + "isSigner": false + }, + { + "name": "newEscrowAuthority", + "isMut": false, + "isSigner": true + }, + { + "name": "newEscrowTokenWallet", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionSetEscrowParams" + } + } + ] + }, + { + "name": "functionResetEscrow", + "accounts": [ + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "mint", + "isMut": false, + "isSigner": false + }, + { + "name": "escrowWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "defaultWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "tokenWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "associatedTokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionResetEscrowParams" + } + } + ] + }, + { + "name": "functionExtendLookup", + "accounts": [ + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "addressLookupTable", + "isMut": true, + "isSigner": false + }, + { + "name": "addressLookupProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionExtendLookupParams" + } + } + ] + }, + { + "name": "functionDeactivateLookup", + "accounts": [ + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "addressLookupTable", + "isMut": true, + "isSigner": false + }, + { + "name": "addressLookupProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [] + }, + { + "name": "functionVerify", + "accounts": [ + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "functionEnclaveSigner", + "isMut": false, + "isSigner": true + }, + { + "name": "verifier", + "isMut": false, + "isSigner": false + }, + { + "name": "verifierSigner", + "isMut": false, + "isSigner": true + }, + { + "name": "verifierPermission", + "isMut": false, + "isSigner": false + }, + { + "name": "escrowWallet", + "isMut": false, + "isSigner": false + }, + { + "name": "escrowTokenWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "receiver", + "isMut": true, + "isSigner": false + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionVerifyParams" + } + } + ] + }, + { + "name": "functionTrigger", + "accounts": [ + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionTriggerParams" + } + } + ] + }, + { + "name": "functionRequestInit", + "accounts": [ + { + "name": "request", + "isMut": true, + "isSigner": true + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "functionAuthority", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "escrow", + "isMut": true, + "isSigner": false + }, + { + "name": "mint", + "isMut": false, + "isSigner": false + }, + { + "name": "state", + "isMut": false, + "isSigner": false + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "associatedTokenProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionRequestInitParams" + } + } + ] + }, + { + "name": "functionRequestSetConfig", + "accounts": [ + { + "name": "request", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionRequestSetConfigParams" + } + } + ] + }, + { + "name": "functionRequestTrigger", + "accounts": [ + { + "name": "request", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "escrow", + "isMut": true, + "isSigner": false + }, + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "state", + "isMut": false, + "isSigner": false + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionRequestTriggerParams" + } + } + ] + }, + { + "name": "functionRequestInitAndTrigger", + "accounts": [ + { + "name": "request", + "isMut": true, + "isSigner": true + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "functionAuthority", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "escrow", + "isMut": true, + "isSigner": false + }, + { + "name": "mint", + "isMut": false, + "isSigner": false + }, + { + "name": "state", + "isMut": false, + "isSigner": false + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "associatedTokenProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionRequestInitAndTriggerParams" + } + } + ] + }, + { + "name": "functionRequestVerify", + "accounts": [ + { + "name": "request", + "isMut": true, + "isSigner": false + }, + { + "name": "functionEnclaveSigner", + "isMut": false, + "isSigner": true + }, + { + "name": "escrow", + "isMut": true, + "isSigner": false + }, + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "functionEscrow", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "verifierQuote", + "isMut": false, + "isSigner": false + }, + { + "name": "verifierEnclaveSigner", + "isMut": false, + "isSigner": true + }, + { + "name": "verifierPermission", + "isMut": false, + "isSigner": false + }, + { + "name": "state", + "isMut": false, + "isSigner": false + }, + { + "name": "attestationQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "receiver", + "isMut": true, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionRequestVerifyParams" + } + } + ] + }, + { + "name": "functionRequestClose", + "accounts": [ + { + "name": "request", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "escrow", + "isMut": true, + "isSigner": false + }, + { + "name": "function", + "isMut": true, + "isSigner": false + }, + { + "name": "solDest", + "isMut": true, + "isSigner": false + }, + { + "name": "escrowDest", + "isMut": true, + "isSigner": false + }, + { + "name": "state", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "FunctionRequestCloseParams" + } + } + ] + } + ], + "accounts": [ + { + "name": "AttestationProgramState", + "type": { + "kind": "struct", + "fields": [ + { + "name": "bump", + "type": "u8" + }, + { + "name": "ebuf", + "type": { + "array": [ + "u8", + 2048 + ] + } + } + ] + } + }, + { + "name": "SwitchboardWallet", + "type": { + "kind": "struct", + "fields": [ + { + "name": "bump", + "type": "u8" + }, + { + "name": "initialized", + "type": "u8" + }, + { + "name": "mint", + "type": "publicKey" + }, + { + "name": "attestationQueue", + "type": "publicKey" + }, + { + "name": "authority", + "type": "publicKey" + }, + { + "name": "name", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "resourceCount", + "type": "u32" + }, + { + "name": "withdrawAuthority", + "type": "publicKey" + }, + { + "name": "tokenWallet", + "type": "publicKey" + }, + { + "name": "resources", + "type": { + "vec": "publicKey" + } + }, + { + "name": "resourcesMaxLen", + "type": "u32" + }, + { + "name": "ebuf", + "docs": [ + "Reserved." + ], + "type": { + "array": [ + "u8", + 64 + ] + } + } + ] + } + }, + { + "name": "FunctionAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "isScheduled", + "docs": [ + "Whether the function is invoked on a schedule or by request" + ], + "type": "u8" + }, + { + "name": "isTriggered", + "docs": [ + "Whether the function has been manually triggered with the function_trigger instruction" + ], + "type": "u8" + }, + { + "name": "permissions", + "docs": [ + "The function permissions granted by the attestation_queue.authority" + ], + "type": "u32" + }, + { + "name": "status", + "type": { + "defined": "FunctionStatus" + } + }, + { + "name": "bump", + "docs": [ + "PDA bump." + ], + "type": "u8" + }, + { + "name": "creatorSeed", + "docs": [ + "The payer who originally created the function. Cannot change, used to derive PDA." + ], + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "name", + "docs": [ + "The name of the function for easier identification." + ], + "type": { + "array": [ + "u8", + 64 + ] + } + }, + { + "name": "metadata", + "docs": [ + "The metadata of the function for easier identification." + ], + "type": { + "array": [ + "u8", + 256 + ] + } + }, + { + "name": "createdAtSlot", + "docs": [ + "The Solana slot when the function was created. (PDA)" + ], + "type": "u64" + }, + { + "name": "createdAt", + "docs": [ + "The unix timestamp when the function was created." + ], + "type": "i64" + }, + { + "name": "updatedAt", + "docs": [ + "The unix timestamp when the function config (container, registry, version, or schedule) was changed." + ], + "type": "i64" + }, + { + "name": "enclave", + "docs": [ + "The enclave quote" + ], + "type": { + "defined": "Quote" + } + }, + { + "name": "mrEnclaves", + "docs": [ + "An array of permitted mr_enclave measurements for the function." + ], + "type": { + "array": [ + { + "array": [ + "u8", + 32 + ] + }, + 32 + ] + } + }, + { + "name": "containerRegistry", + "docs": [ + "The off-chain registry to fetch the function container from." + ], + "type": { + "array": [ + "u8", + 64 + ] + } + }, + { + "name": "container", + "docs": [ + "The identifier of the container in the given container_registry." + ], + "type": { + "array": [ + "u8", + 64 + ] + } + }, + { + "name": "version", + "docs": [ + "The version tag of the container to pull." + ], + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "paramsSchema", + "docs": [ + "The expected schema for the container params." + ], + "type": { + "array": [ + "u8", + 256 + ] + } + }, + { + "name": "defaultContainerParams", + "docs": [ + "The default params passed to the container during scheduled execution." + ], + "type": { + "array": [ + "u8", + 256 + ] + } + }, + { + "name": "authority", + "docs": [ + "The authority of the function which is authorized to make account changes." + ], + "type": "publicKey" + }, + { + "name": "attestationQueue", + "docs": [ + "The address of the AttestationQueueAccountData that will be processing function requests and verifying the function measurements." + ], + "type": "publicKey" + }, + { + "name": "queueIdx", + "docs": [ + "An incrementer used to rotate through an AttestationQueue's verifiers." + ], + "type": "u32" + }, + { + "name": "addressLookupTable", + "docs": [ + "The address_lookup_table of the function used to increase the number of accounts we can fit into a function result." + ], + "type": "publicKey" + }, + { + "name": "schedule", + "docs": [ + "The cron schedule to run the function on." + ], + "type": { + "array": [ + "u8", + 64 + ] + } + }, + { + "name": "lastExecutionTimestamp", + "docs": [ + "The unix timestamp when the function was last run." + ], + "type": "i64" + }, + { + "name": "nextAllowedTimestamp", + "docs": [ + "The unix timestamp when the function is allowed to run next." + ], + "type": "i64" + }, + { + "name": "triggerCount", + "docs": [ + "The number of times to trigger the function upon the next invocation." + ], + "type": "u64" + }, + { + "name": "triggeredSince", + "docs": [ + "Time this function has been sitting in an explicitly triggered state" + ], + "type": "i64" + }, + { + "name": "permissionExpiration", + "docs": [ + "UNUSED. The unix timestamp when the current permissions expire." + ], + "type": "i64" + }, + { + "name": "numRequests", + "docs": [ + "Number of requests created for this function. Used to prevent closing when there are live requests." + ], + "type": "u64" + }, + { + "name": "requestsDisabled", + "docs": [ + "Whether custom requests have been disabled for this function." + ], + "type": "bool" + }, + { + "name": "requestsRequireAuthorization", + "docs": [ + "Whether new requests need to be authorized by the FunctionAccount authority before being initialized.", + "Useful if you want to use CPIs to control request account creation." + ], + "type": "bool" + }, + { + "name": "reserved1", + "docs": [ + "DEPRECATED." + ], + "type": { + "array": [ + "u8", + 8 + ] + } + }, + { + "name": "requestsFee", + "docs": [ + "The lamports paid to the FunctionAccount escrow on each successful update request." + ], + "type": "u64" + }, + { + "name": "escrowWallet", + "docs": [ + "The SwitchboardWallet that will handle pre-funding rewards paid out to function runners." + ], + "type": "publicKey" + }, + { + "name": "escrowTokenWallet", + "docs": [ + "The escrow_wallet TokenAccount that handles pre-funding rewards paid out to function runners." + ], + "type": "publicKey" + }, + { + "name": "rewardEscrowWallet", + "docs": [ + "The SwitchboardWallet that will handle acruing rewards from requests.", + "Defaults to the escrow_wallet." + ], + "type": "publicKey" + }, + { + "name": "rewardEscrowTokenWallet", + "docs": [ + "The reward_escrow_wallet TokenAccount used to acrue rewards from requests made with custom parameters." + ], + "type": "publicKey" + }, + { + "name": "ebuf", + "docs": [ + "Reserved." + ], + "type": { + "array": [ + "u8", + 1024 + ] + } + } + ] + } + }, + { + "name": "FunctionRequestAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "isTriggered", + "docs": [ + "Whether the request is ready to be processed." + ], + "type": "u8" + }, + { + "name": "status", + "docs": [ + "The status of the current request." + ], + "type": { + "defined": "RequestStatus" + } + }, + { + "name": "authority", + "docs": [ + "Signer allowed to cancel the request." + ], + "type": "publicKey" + }, + { + "name": "payer", + "docs": [ + "The default destination for rent exemption when the account is closed." + ], + "type": "publicKey" + }, + { + "name": "function", + "docs": [ + "The function that can process this request" + ], + "type": "publicKey" + }, + { + "name": "escrow", + "docs": [ + "The tokenAccount escrow" + ], + "type": "publicKey" + }, + { + "name": "attestationQueue", + "docs": [ + "The Attestation Queue for this request." + ], + "type": "publicKey" + }, + { + "name": "activeRequest", + "docs": [ + "The current active request." + ], + "type": { + "defined": "FunctionRequestTriggerRound" + } + }, + { + "name": "previousRequest", + "docs": [ + "The previous request." + ], + "type": { + "defined": "FunctionRequestTriggerRound" + } + }, + { + "name": "maxContainerParamsLen", + "docs": [ + "The maximum number of bytes to pass to the container params." + ], + "type": "u32" + }, + { + "name": "containerParamsHash", + "docs": [ + "Hash of the serialized container_params to prevent RPC tampering.", + "Should be verified within your function to ensure you are using the correct parameters." + ], + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "containerParams", + "docs": [ + "The stringified container params to pass to the function." + ], + "type": "bytes" + }, + { + "name": "createdAt", + "docs": [ + "The unix timestamp when the function was created." + ], + "type": "i64" + }, + { + "name": "garbageCollectionSlot", + "docs": [ + "The slot when the account can be garbage collected and closed by anyone for a portion of the rent." + ], + "type": { + "option": "u64" + } + }, + { + "name": "ebuf", + "docs": [ + "Reserved." + ], + "type": { + "array": [ + "u8", + 256 + ] + } + } + ] + } + }, + { + "name": "VerifierAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "enclave", + "docs": [ + "Represents the state of the quote verifiers enclave." + ], + "type": { + "defined": "Quote" + } + }, + { + "name": "authority", + "docs": [ + "The authority of the EnclaveAccount which is permitted to make account changes." + ], + "type": "publicKey" + }, + { + "name": "attestationQueue", + "docs": [ + "Queue used for attestation to verify a MRENCLAVE measurement." + ], + "type": "publicKey" + }, + { + "name": "createdAt", + "docs": [ + "The unix timestamp when the quote was created." + ], + "type": "i64" + }, + { + "name": "isOnQueue", + "docs": [ + "Whether the quote is located on the AttestationQueues buffer." + ], + "type": "bool" + }, + { + "name": "lastHeartbeat", + "docs": [ + "The last time the quote heartbeated on-chain." + ], + "type": "i64" + }, + { + "name": "rewardEscrow", + "docs": [ + "The SwitchboardWallet account containing the reward escrow for verifying quotes on-chain.", + "We should set this whenever the operator changes so we dont need to pass another account and can verify with has_one." + ], + "type": "publicKey" + }, + { + "name": "stakeWallet", + "docs": [ + "The SwitchboardWallet account containing the queues required min_stake.", + "Needs to be separate from the reward_escrow. Allows easier 3rd party management of stake from rewards." + ], + "type": "publicKey" + }, + { + "name": "ebuf", + "docs": [ + "Reserved." + ], + "type": { + "array": [ + "u8", + 1024 + ] + } + } + ] + } + }, + { + "name": "AttestationQueueAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "authority", + "docs": [ + "The address of the authority which is permitted to add/remove allowed enclave measurements." + ], + "type": "publicKey" + }, + { + "name": "mrEnclaves", + "docs": [ + "Allowed enclave measurements." + ], + "type": { + "array": [ + { + "array": [ + "u8", + 32 + ] + }, + 32 + ] + } + }, + { + "name": "mrEnclavesLen", + "docs": [ + "The number of allowed enclave measurements." + ], + "type": "u32" + }, + { + "name": "data", + "docs": [ + "The addresses of the quote verifiers who have a valid", + "verification status and have heartbeated on-chain recently." + ], + "type": { + "array": [ + "publicKey", + 128 + ] + } + }, + { + "name": "dataLen", + "docs": [ + "The length of valid quote verifiers for the given attestation queue." + ], + "type": "u32" + }, + { + "name": "allowAuthorityOverrideAfter", + "docs": [ + "Allow authority to force add a node after X seconds with no heartbeat." + ], + "type": "i64" + }, + { + "name": "requireAuthorityHeartbeatPermission", + "docs": [ + "Even if a heartbeating machine quote verifies with proper measurement,", + "require authority signoff." + ], + "type": "bool" + }, + { + "name": "requireUsagePermissions", + "docs": [ + "Require FunctionAccounts to have PermitQueueUsage before they are executed." + ], + "type": "bool" + }, + { + "name": "maxQuoteVerificationAge", + "docs": [ + "The maximum allowable time until a EnclaveAccount needs to be re-verified on-chain." + ], + "type": "i64" + }, + { + "name": "reward", + "docs": [ + "The reward paid to quote verifiers for attesting on-chain." + ], + "type": "u32" + }, + { + "name": "lastHeartbeat", + "docs": [ + "The unix timestamp when the last quote verifier heartbeated on-chain." + ], + "type": "i64" + }, + { + "name": "nodeTimeout", + "type": "i64" + }, + { + "name": "currIdx", + "docs": [ + "Incrementer used to track the current quote verifier permitted to run any available functions." + ], + "type": "u32" + }, + { + "name": "gcIdx", + "docs": [ + "Incrementer used to garbage collect and remove stale quote verifiers." + ], + "type": "u32" + }, + { + "name": "verifierMinStake", + "docs": [ + "The minimum number of lamports a quote verifier needs to lock-up in order to heartbeat and verify other quotes." + ], + "type": "u64" + }, + { + "name": "functionMinStake", + "docs": [ + "The minimum number of lamports a function needs to lock-up in order to use a queues resources." + ], + "type": "u64" + }, + { + "name": "ebuf", + "docs": [ + "Reserved." + ], + "type": { + "array": [ + "u8", + 1008 + ] + } + } + ] + } + }, + { + "name": "AttestationPermissionAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "authority", + "type": "publicKey" + }, + { + "name": "permissions", + "type": "u32" + }, + { + "name": "granter", + "type": "publicKey" + }, + { + "name": "grantee", + "type": "publicKey" + }, + { + "name": "expiration", + "type": "i64" + }, + { + "name": "bump", + "type": "u8" + }, + { + "name": "ebuf", + "type": { + "array": [ + "u8", + 256 + ] + } + } + ] + } + } + ], + "types": [ + { + "name": "FunctionCloseParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "FunctionExtendLookupParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "newAddresses", + "type": { + "vec": "publicKey" + } + } + ] + } + }, + { + "name": "FunctionInitParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "type": "bytes" + }, + { + "name": "metadata", + "type": "bytes" + }, + { + "name": "container", + "type": "bytes" + }, + { + "name": "containerRegistry", + "type": "bytes" + }, + { + "name": "version", + "type": "bytes" + }, + { + "name": "schedule", + "type": "bytes" + }, + { + "name": "mrEnclave", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "recentSlot", + "type": "u64" + }, + { + "name": "requestsDisabled", + "type": "bool" + }, + { + "name": "requestsRequireAuthorization", + "type": "bool" + }, + { + "name": "requestsFee", + "type": "u64" + }, + { + "name": "creatorSeed", + "type": { + "option": { + "array": [ + "u8", + 32 + ] + } + } + } + ] + } + }, + { + "name": "FunctionResetEscrowParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "FunctionSetAuthorityParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "FunctionSetConfigParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "type": { + "option": "bytes" + } + }, + { + "name": "metadata", + "type": { + "option": "bytes" + } + }, + { + "name": "container", + "type": { + "option": "bytes" + } + }, + { + "name": "containerRegistry", + "type": { + "option": "bytes" + } + }, + { + "name": "version", + "type": { + "option": "bytes" + } + }, + { + "name": "schedule", + "type": { + "option": "bytes" + } + }, + { + "name": "mrEnclaves", + "type": { + "option": { + "vec": { + "array": [ + "u8", + 32 + ] + } + } + } + }, + { + "name": "requestsDisabled", + "type": { + "option": "bool" + } + }, + { + "name": "requestsRequireAuthorization", + "type": { + "option": "bool" + } + }, + { + "name": "requestsFee", + "type": { + "option": "u64" + } + } + ] + } + }, + { + "name": "FunctionSetEscrowParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "FunctionTriggerParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "FunctionVerifyParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "observedTime", + "type": "i64" + }, + { + "name": "nextAllowedTimestamp", + "type": "i64" + }, + { + "name": "isFailure", + "type": "bool" + }, + { + "name": "mrEnclave", + "type": { + "array": [ + "u8", + 32 + ] + } + } + ] + } + }, + { + "name": "AttestationPermissionInitParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "AttestationPermissionSetParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "permission", + "type": "u32" + }, + { + "name": "enable", + "type": "bool" + } + ] + } + }, + { + "name": "AttestationQueueAddMrEnclaveParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "mrEnclave", + "type": { + "array": [ + "u8", + 32 + ] + } + } + ] + } + }, + { + "name": "AttestationQueueInitParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "allowAuthorityOverrideAfter", + "type": "u32" + }, + { + "name": "requireAuthorityHeartbeatPermission", + "type": "bool" + }, + { + "name": "requireUsagePermissions", + "type": "bool" + }, + { + "name": "maxQuoteVerificationAge", + "type": "u32" + }, + { + "name": "reward", + "type": "u32" + }, + { + "name": "nodeTimeout", + "type": "u32" + } + ] + } + }, + { + "name": "AttestationQueueRemoveMrEnclaveParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "mrEnclave", + "type": { + "array": [ + "u8", + 32 + ] + } + } + ] + } + }, + { + "name": "FunctionRequestCloseParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "FunctionRequestInitParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "maxContainerParamsLen", + "type": { + "option": "u32" + } + }, + { + "name": "containerParams", + "type": "bytes" + }, + { + "name": "garbageCollectionSlot", + "type": { + "option": "u64" + } + } + ] + } + }, + { + "name": "FunctionRequestInitAndTriggerParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "bounty", + "type": { + "option": "u64" + } + }, + { + "name": "slotsUntilExpiration", + "type": { + "option": "u64" + } + }, + { + "name": "maxContainerParamsLen", + "type": { + "option": "u32" + } + }, + { + "name": "containerParams", + "type": { + "option": "bytes" + } + }, + { + "name": "garbageCollectionSlot", + "type": { + "option": "u64" + } + }, + { + "name": "validAfterSlot", + "type": { + "option": "u64" + } + } + ] + } + }, + { + "name": "FunctionRequestSetConfigParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "containerParams", + "type": "bytes" + }, + { + "name": "appendContainerParams", + "type": "bool" + } + ] + } + }, + { + "name": "FunctionRequestTriggerParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "bounty", + "type": { + "option": "u64" + } + }, + { + "name": "slotsUntilExpiration", + "type": { + "option": "u64" + } + }, + { + "name": "validAfterSlot", + "type": { + "option": "u64" + } + } + ] + } + }, + { + "name": "FunctionRequestVerifyParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "observedTime", + "type": "i64" + }, + { + "name": "isFailure", + "type": "bool" + }, + { + "name": "mrEnclave", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "requestSlot", + "type": "u64" + }, + { + "name": "containerParamsHash", + "type": { + "array": [ + "u8", + 32 + ] + } + } + ] + } + }, + { + "name": "StateInitParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "VerifierHeartbeatParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "VerifierInitParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "VerifierQuoteRotateParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "registryKey", + "type": { + "array": [ + "u8", + 64 + ] + } + } + ] + } + }, + { + "name": "VerifierQuoteVerifyParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "timestamp", + "type": "i64" + }, + { + "name": "mrEnclave", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "idx", + "type": "u32" + } + ] + } + }, + { + "name": "WalletCloseParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "WalletFundParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "transferAmount", + "type": { + "option": "u64" + } + }, + { + "name": "wrapAmount", + "type": { + "option": "u64" + } + } + ] + } + }, + { + "name": "WalletInitParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "type": "bytes" + }, + { + "name": "maxLen", + "type": { + "option": "u32" + } + } + ] + } + }, + { + "name": "WalletWithdrawParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "amount", + "type": "u64" + } + ] + } + }, + { + "name": "FunctionRequestTriggerRound", + "type": { + "kind": "struct", + "fields": [ + { + "name": "status", + "docs": [ + "The status of the request." + ], + "type": { + "defined": "RequestStatus" + } + }, + { + "name": "bounty", + "docs": [ + "The SOL bounty in lamports used to incentivize a verifier to expedite the request." + ], + "type": "u64" + }, + { + "name": "requestSlot", + "docs": [ + "The slot the request was published" + ], + "type": "u64" + }, + { + "name": "fulfilledSlot", + "docs": [ + "The slot when the request was fulfilled" + ], + "type": "u64" + }, + { + "name": "expirationSlot", + "docs": [ + "The slot when the request will expire and be able to be closed by the non-authority account" + ], + "type": "u64" + }, + { + "name": "verifier", + "docs": [ + "The EnclaveAccount who verified the enclave for this request" + ], + "type": "publicKey" + }, + { + "name": "enclaveSigner", + "docs": [ + "The keypair generated in the enclave and required to sign any", + "valid transactions processed by the function." + ], + "type": "publicKey" + }, + { + "name": "validAfterSlot", + "docs": [ + "The slot when the request can first be executed." + ], + "type": "u64" + }, + { + "name": "ebuf", + "docs": [ + "Reserved." + ], + "type": { + "array": [ + "u8", + 56 + ] + } + } + ] + } + }, + { + "name": "Quote", + "type": { + "kind": "struct", + "fields": [ + { + "name": "enclaveSigner", + "docs": [ + "The address of the signer generated within an enclave." + ], + "type": "publicKey" + }, + { + "name": "mrEnclave", + "docs": [ + "The quotes MRENCLAVE measurement dictating the contents of the secure enclave." + ], + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "verificationStatus", + "docs": [ + "The VerificationStatus of the quote." + ], + "type": "u8" + }, + { + "name": "verificationTimestamp", + "docs": [ + "The unix timestamp when the quote was last verified." + ], + "type": "i64" + }, + { + "name": "validUntil", + "docs": [ + "The unix timestamp when the quotes verification status expires." + ], + "type": "i64" + }, + { + "name": "quoteRegistry", + "docs": [ + "The off-chain registry where the verifiers quote can be located." + ], + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "registryKey", + "docs": [ + "Key to lookup the buffer data on IPFS or an alternative decentralized storage solution." + ], + "type": { + "array": [ + "u8", + 64 + ] + } + }, + { + "name": "ebuf", + "docs": [ + "Reserved." + ], + "type": { + "array": [ + "u8", + 256 + ] + } + } + ] + } + }, + { + "name": "FunctionStatus", + "type": { + "kind": "enum", + "variants": [ + { + "name": "None" + }, + { + "name": "Active" + }, + { + "name": "NonExecutable" + }, + { + "name": "None3" + }, + { + "name": "Expired" + }, + { + "name": "None5" + }, + { + "name": "None6" + }, + { + "name": "None7" + }, + { + "name": "OutOfFunds" + }, + { + "name": "None9" + }, + { + "name": "None10" + }, + { + "name": "None11" + }, + { + "name": "None12" + }, + { + "name": "None13" + }, + { + "name": "None14" + }, + { + "name": "None15" + }, + { + "name": "InvalidPermissions" + } + ] + } + }, + { + "name": "FundingStatus", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Inactive" + }, + { + "name": "Active" + } + ] + } + }, + { + "name": "RequestStatus", + "type": { + "kind": "enum", + "variants": [ + { + "name": "None" + }, + { + "name": "RequestPending" + }, + { + "name": "RequestCancelled" + }, + { + "name": "RequestFailure" + }, + { + "name": "RequestExpired" + }, + { + "name": "RequestSuccess" + } + ] + } + }, + { + "name": "VerificationStatus", + "type": { + "kind": "enum", + "variants": [ + { + "name": "None" + }, + { + "name": "VerificationPending" + }, + { + "name": "VerificationFailure" + }, + { + "name": "None3" + }, + { + "name": "VerificationSuccess" + }, + { + "name": "None5" + }, + { + "name": "None6" + }, + { + "name": "None7" + }, + { + "name": "VerificationOverride" + } + ] + } + }, + { + "name": "SwitchboardAttestationPermission", + "type": { + "kind": "enum", + "variants": [ + { + "name": "None" + }, + { + "name": "PermitNodeheartbeat" + }, + { + "name": "PermitQueueUsage" + } + ] + } + } + ], + "events": [ + { + "name": "FunctionFundEvent", + "fields": [ + { + "name": "function", + "type": "publicKey", + "index": false + }, + { + "name": "amount", + "type": "u64", + "index": false + } + ] + }, + { + "name": "FunctionRequestInitEvent", + "fields": [ + { + "name": "attestationQueue", + "type": "publicKey", + "index": false + }, + { + "name": "function", + "type": "publicKey", + "index": false + }, + { + "name": "request", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "FunctionRequestTriggerEvent", + "fields": [ + { + "name": "attestationQueue", + "type": "publicKey", + "index": false + }, + { + "name": "request", + "type": "publicKey", + "index": false + }, + { + "name": "function", + "type": "publicKey", + "index": false + }, + { + "name": "containerRegistry", + "type": "bytes", + "index": false + }, + { + "name": "container", + "type": "bytes", + "index": false + }, + { + "name": "bounty", + "type": "u64", + "index": false + }, + { + "name": "requestSlot", + "type": "u64", + "index": false + }, + { + "name": "expirationSlot", + "type": "u64", + "index": false + }, + { + "name": "containerParamsHash", + "type": "bytes", + "index": false + } + ] + }, + { + "name": "FunctionRequestVerifyEvent", + "fields": [ + { + "name": "request", + "type": "publicKey", + "index": false + }, + { + "name": "function", + "type": "publicKey", + "index": false + }, + { + "name": "verifier", + "type": "publicKey", + "index": false + }, + { + "name": "containerRegistry", + "type": "bytes", + "index": false + }, + { + "name": "container", + "type": "bytes", + "index": false + }, + { + "name": "params", + "type": "bytes", + "index": false + } + ] + }, + { + "name": "FunctionRequestCloseEvent", + "fields": [ + { + "name": "request", + "type": "publicKey", + "index": false + }, + { + "name": "slot", + "type": "u64", + "index": false + } + ] + }, + { + "name": "FunctionTriggerEvent", + "fields": [ + { + "name": "function", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "FunctionInitEvent", + "fields": [ + { + "name": "function", + "type": "publicKey", + "index": false + }, + { + "name": "containerRegistry", + "type": "bytes", + "index": false + }, + { + "name": "container", + "type": "bytes", + "index": false + }, + { + "name": "version", + "type": "bytes", + "index": false + }, + { + "name": "schedule", + "type": "bytes", + "index": false + }, + { + "name": "mrEnclave", + "type": "bytes", + "index": false + } + ] + }, + { + "name": "FunctionSetConfigEvent", + "fields": [ + { + "name": "function", + "type": "publicKey", + "index": false + }, + { + "name": "containerRegistry", + "type": "bytes", + "index": false + }, + { + "name": "container", + "type": "bytes", + "index": false + }, + { + "name": "version", + "type": "bytes", + "index": false + }, + { + "name": "schedule", + "type": "bytes", + "index": false + }, + { + "name": "mrEnclaves", + "type": { + "vec": "bytes" + }, + "index": false + } + ] + }, + { + "name": "FunctionBootedEvent", + "fields": [ + { + "name": "function", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "FunctionVerifyEvent", + "fields": [ + { + "name": "function", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "FunctionWithdrawEvent", + "fields": [ + { + "name": "function", + "type": "publicKey", + "index": false + }, + { + "name": "amount", + "type": "u64", + "index": false + } + ] + }, + { + "name": "PermissionInitEvent", + "fields": [ + { + "name": "permission", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "PermissionSetEvent", + "fields": [ + { + "name": "permission", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "QueueAddMrEnclaveEvent", + "fields": [ + { + "name": "queue", + "type": "publicKey", + "index": false + }, + { + "name": "mrEnclave", + "type": { + "array": [ + "u8", + 32 + ] + }, + "index": false + } + ] + }, + { + "name": "QueueInitEvent", + "fields": [ + { + "name": "queue", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "QueueRemoveMrEnclaveEvent", + "fields": [ + { + "name": "queue", + "type": "publicKey", + "index": false + }, + { + "name": "mrEnclave", + "type": { + "array": [ + "u8", + 32 + ] + }, + "index": false + } + ] + }, + { + "name": "VerifierHeartbeatEvent", + "fields": [ + { + "name": "verifier", + "type": "publicKey", + "index": false + }, + { + "name": "queue", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "VerifierInitEvent", + "fields": [ + { + "name": "verifier", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "VerifierQuoteRotateEvent", + "fields": [ + { + "name": "verifier", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "VerifierQuoteOverrideEvent", + "fields": [ + { + "name": "verifier", + "type": "publicKey", + "index": false + }, + { + "name": "queue", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "GarbageCollectionEvent", + "fields": [ + { + "name": "verifier", + "type": "publicKey", + "index": false + }, + { + "name": "queue", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "VerifierQuoteVerifyEvent", + "fields": [ + { + "name": "quote", + "type": "publicKey", + "index": false + }, + { + "name": "queue", + "type": "publicKey", + "index": false + }, + { + "name": "verifier", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "VerifierQuoteVerifyRequestEvent", + "fields": [ + { + "name": "quote", + "type": "publicKey", + "index": false + }, + { + "name": "verifier", + "type": "publicKey", + "index": false + } + ] + } + ], + "errors": [ + { + "code": 6000, + "name": "GenericError" + }, + { + "code": 6001, + "name": "InvalidQuote", + "msg": "The provided enclave quote is invalid" + }, + { + "code": 6002, + "name": "QuoteExpired", + "msg": "The EnclaveAccount has expired and needs to be reverified" + }, + { + "code": 6003, + "name": "InvalidNode" + }, + { + "code": 6004, + "name": "InsufficientQueue" + }, + { + "code": 6005, + "name": "QueueFull", + "msg": "The provided queue is full and cannot support new verifiers" + }, + { + "code": 6006, + "name": "InvalidEnclaveSigner", + "msg": "The provided enclave_signer does not match the expected enclave_signer on the EnclaveAccount" + }, + { + "code": 6007, + "name": "InvalidSigner" + }, + { + "code": 6008, + "name": "MrEnclavesEmpty", + "msg": "This account has zero mr_enclaves defined" + }, + { + "code": 6009, + "name": "MrEnclaveAlreadyExists", + "msg": "The MrEnclave value already exists in the array" + }, + { + "code": 6010, + "name": "MrEnclaveDoesntExist", + "msg": "The MrEnclave value was not found in the whitelist" + }, + { + "code": 6011, + "name": "MrEnclaveAtCapacity", + "msg": "This account has a full mr_enclaves array. Remove some measurements to make room for new ones" + }, + { + "code": 6012, + "name": "PermissionDenied", + "msg": "The PermissionAccount is missing the required flags for this action. Check the queues config to see which permissions are required" + }, + { + "code": 6013, + "name": "InvalidConstraint" + }, + { + "code": 6014, + "name": "InvalidTimestamp" + }, + { + "code": 6015, + "name": "InvalidMrEnclave" + }, + { + "code": 6016, + "name": "InvalidReportData" + }, + { + "code": 6017, + "name": "InsufficientLoadAmount" + }, + { + "code": 6018, + "name": "IncorrectObservedTime" + }, + { + "code": 6019, + "name": "InvalidQuoteMode" + }, + { + "code": 6020, + "name": "InvalidVerifierIdx" + }, + { + "code": 6021, + "name": "InvalidSelfVerifyRequest" + }, + { + "code": 6022, + "name": "IncorrectMrEnclave" + }, + { + "code": 6023, + "name": "InvalidResponder" + }, + { + "code": 6024, + "name": "InvalidAddressLookupAddress", + "msg": "The provided address_lookup_address did not match the expected address on-chain" + }, + { + "code": 6025, + "name": "InvalidQueue", + "msg": "The provided attestation queue address did not match the expected address on-chain" + }, + { + "code": 6026, + "name": "IllegalVerifier" + }, + { + "code": 6027, + "name": "InvalidEscrow" + }, + { + "code": 6028, + "name": "InvalidAuthority", + "msg": "The provided authority account does not match the expected value on-chain" + }, + { + "code": 6029, + "name": "IllegalExecuteAttempt" + }, + { + "code": 6030, + "name": "RequestExpired", + "msg": "The requests expirationSlot has expired" + }, + { + "code": 6031, + "name": "InsufficientFunds", + "msg": "The escrow has insufficient funds for this action" + }, + { + "code": 6032, + "name": "MissingFunctionEscrow", + "msg": "The FunctionAccount escrow is required if function.requests_fee is greater than zero" + }, + { + "code": 6033, + "name": "InvalidRequest", + "msg": "The provided requestSlot did not match the expected requestSlot on-chain. The request may have already been processed" + }, + { + "code": 6034, + "name": "FunctionNotReady", + "msg": "The FunctionAccount status is not active (1)" + }, + { + "code": 6035, + "name": "UserRequestsDisabled", + "msg": "The FunctionAccount has set requests_disabled to true and disabled this action" + }, + { + "code": 6036, + "name": "MissingFunctionAuthority", + "msg": "The FunctionAccount authority is required to sign if function.requests_require_authorization is enabled" + }, + { + "code": 6037, + "name": "FunctionCloseNotReady", + "msg": "The FunctionAccount must have no requests before it can be closed" + }, + { + "code": 6038, + "name": "RequestAlreadyInitialized", + "msg": "Attempting to initialize an already created FunctionRequestAccount" + }, + { + "code": 6039, + "name": "AccountCloseNotPermitted" + }, + { + "code": 6040, + "name": "AccountCloseNotReady" + }, + { + "code": 6041, + "name": "FunctionRequestNotReady", + "msg": "The FunctionRequestAccount is not ready to be verified" + } + ] +} \ No newline at end of file diff --git a/javascript/solana.js/package.json b/javascript/solana.js/package.json index 9d0d7cb95..a34ec1ac3 100644 --- a/javascript/solana.js/package.json +++ b/javascript/solana.js/package.json @@ -1,116 +1,10 @@ { "name": "@switchboard-xyz/solana.js", - "version": "2.8.1", - "author": "", - "license": "MIT", + "version": "3.1.2", "description": "A Typescript client to interact with Switchboard on Solana.", + "license": "MIT", + "author": "", "type": "module", - "main": "./index.js", - "types": "./index.d.ts", - "scripts": { - "close-functions": "tsx ./scripts/close-functions.ts", - "keypair:create": "pnpm exec shx find ~/.config/solana/id.json || solana-keygen new -s --no-bip39-passphrase --outfile ~/.config/solana/id.json", - "localnet:down": "kill -9 $(pgrep command solana-test-validator) || exit 0", - "localnet": "tsx ./scripts/localnet.ts", - "local:validator": "shx mkdir -p .anchor/test-ledger || true; solana-test-validator -q -r --ledger .anchor/test-ledger --mint $(solana-keygen pubkey ~/.config/solana/id.json) --bind-address 0.0.0.0 --url https://api.devnet.solana.com --rpc-port 8899 --clone SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f `# programId` --clone 7nYabs9dUhvxYwdTnrWVBL9MYviKSfrEbdWCUbcnwkpF `# programDataAddress` --clone Fi8vncGpNKbq62gPo56G4toCehWNy77GgqGkTaAF5Lkk `# idlAddress` --clone sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx `# sgxProgramId` --clone BzqtGXZPiDSinP4xMFgPf6FLgSa6iPufK4m4JJFgMnTK `# sgxProgramDataAddress` --clone 5MFs7RGTjLi1wtKNBFRtuLipCkkjs4YQwRRU9sjnbQbS `# sgxProgramState` --clone 5ExuoQR69trmKQfB95fDsUGsUrrChbGq9PFgt8qouncz `# sgxIdlAddress` --clone CyZuD7RPDcrqCGbNvLCyqk6Py9cEZTKmNKujfPi3ynDd `# programState` --clone 7hkp1xfPBcD2t1vZMoWWQPzipHVcXeLAAaiGXdPSfDie `# switchboardVault`", - "local:validator:mainnet": "solana-test-validator -q -r --ledger .anchor/test-ledger --mint $(solana-keygen pubkey ~/.config/solana/id.json) --bind-address 0.0.0.0 --rpc-port 8899 --url https://api.mainnet-beta.solana.com --clone SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f --clone 7nYabs9dUhvxYwdTnrWVBL9MYviKSfrEbdWCUbcnwkpF --clone Fi8vncGpNKbq62gPo56G4toCehWNy77GgqGkTaAF5Lkk --clone sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx --clone BzqtGXZPiDSinP4xMFgPf6FLgSa6iPufK4m4JJFgMnTK --clone 5MFs7RGTjLi1wtKNBFRtuLipCkkjs4YQwRRU9sjnbQbS --clone 5ExuoQR69trmKQfB95fDsUGsUrrChbGq9PFgt8qouncz --clone CyZuD7RPDcrqCGbNvLCyqk6Py9cEZTKmNKujfPi3ynDd --clone J7nSEX8ADf3pVVicd6yKy2Skvg8iLePEmkLUisAAaioD", - "generate": "tsx ./scripts/generate-client.ts", - "build": "node esbuild.js", - "watch": "pnpm exec tsc -p tsconfig.cjs.json --watch", - "test": "node ./node_modules/mocha/bin/mocha --loader=ts-node/esm --extension ts --timeout 60000 --exit", - "test:localnet": "SOLANA_LOCALNET=1 node ./node_modules/mocha/bin/mocha --exit", - "test:localnet:mainnet": "SWITCHBOARD_PROGRAM_ID=SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f SOLANA_LOCALNET=1 SOLANA_CLUSTER=mainnet-beta node ./node_modules/mocha/bin/mocha --loader=ts-node/esm --extension ts --timeout 60000 --exit", - "lint": "pnpm exec eslint src", - "clean": "pnpm exec rimraf node_modules lib .turbo", - "fix": "pnpm exec eslint --fix src" - }, - "dependencies": { - "@coral-xyz/anchor": "^0.28.0", - "@coral-xyz/borsh": "^0.28.0", - "@solana/spl-token": "^0.3.8", - "@solana/web3.js": "^1.78.3", - "@switchboard-xyz/common": "^2.3.6", - "cron-validator": "^1.3.1", - "dotenv": "^16.3.1", - "lodash": "^4.17.21" - }, - "devDependencies": { - "@switchboard-xyz/eslint-config": "latest", - "@switchboard-xyz/oracle": "latest", - "@types/chai": "^4.3.5", - "@types/lodash": "^4.14.195", - "@types/mocha": "^10.0.1", - "@types/shelljs": "^0.8.12", - "anchor-client-gen": "^0.28.1", - "chai": "^4.3.7", - "chalk": "^4.1.2", - "esbuild": "^0.17.19", - "mocha": "^10.2.0", - "shelljs": "^0.8.5", - "ts-mocha": "^10.0.0", - "ts-node": "^10.9.1", - "tsx": "^3.12.7", - "typedoc": "^0.23.28" - }, - "pre-commit": [ - "build" - ], - "engines": { - "npm": ">=7.0.0", - "node": ">=16.0.0" - }, - "files": [ - "lib/", - "package.json", - "index.cjs", - "index.js", - "index.d.ts", - "SwitchboardProgram.cjs", - "SwitchboardProgram.js", - "SwitchboardProgram.d.ts", - "TransactionObject.cjs", - "TransactionObject.js", - "TransactionObject.d.ts", - "AggregatorAccount.cjs", - "AggregatorAccount.js", - "AggregatorAccount.d.ts", - "generated.cjs", - "generated.js", - "generated.d.ts", - "generated/accounts.cjs", - "generated/accounts.js", - "generated/accounts.d.ts", - "generated/instructions.cjs", - "generated/instructions.js", - "generated/instructions.d.ts", - "generated/types.cjs", - "generated/types.js", - "generated/types.d.ts", - "generated/oracle.cjs", - "generated/oracle.js", - "generated/oracle.d.ts", - "generated/oracle/accounts.cjs", - "generated/oracle/accounts.js", - "generated/oracle/accounts.d.ts", - "generated/oracle/instructions.cjs", - "generated/oracle/instructions.js", - "generated/oracle/instructions.d.ts", - "generated/oracle/types.cjs", - "generated/oracle/types.js", - "generated/oracle/types.d.ts", - "generated/attestation.cjs", - "generated/attestation.js", - "generated/attestation.d.ts", - "generated/attestation/accounts.cjs", - "generated/attestation/accounts.js", - "generated/attestation/accounts.d.ts", - "generated/attestation/instructions.cjs", - "generated/attestation/instructions.js", - "generated/attestation/instructions.d.ts", - "generated/attestation/types.cjs", - "generated/attestation/types.js", - "generated/attestation/types.d.ts" - ], "exports": { ".": { "types": "./index.d.ts", @@ -137,6 +31,11 @@ "import": "./generated.js", "require": "./generated.cjs" }, + "./runner": { + "types": "./runner.d.ts", + "import": "./runner.js", + "require": "./runner.cjs" + }, "./generated/accounts": { "types": "./generated/accounts.d.ts", "import": "./generated/accounts.js", @@ -193,5 +92,117 @@ "require": "./generated/attestation/types.cjs" }, "./package.json": "./package.json" + }, + "main": "./index.js", + "types": "./index.d.ts", + "files": [ + "lib/", + "package.json", + "index.cjs", + "index.js", + "index.d.ts", + "SwitchboardProgram.cjs", + "SwitchboardProgram.js", + "SwitchboardProgram.d.ts", + "TransactionObject.cjs", + "TransactionObject.js", + "TransactionObject.d.ts", + "AggregatorAccount.cjs", + "AggregatorAccount.js", + "AggregatorAccount.d.ts", + "generated.cjs", + "generated.js", + "generated.d.ts", + "runner.cjs", + "runner.js", + "runner.d.ts", + "generated/accounts.cjs", + "generated/accounts.js", + "generated/accounts.d.ts", + "generated/instructions.cjs", + "generated/instructions.js", + "generated/instructions.d.ts", + "generated/types.cjs", + "generated/types.js", + "generated/types.d.ts", + "generated/oracle.cjs", + "generated/oracle.js", + "generated/oracle.d.ts", + "generated/oracle/accounts.cjs", + "generated/oracle/accounts.js", + "generated/oracle/accounts.d.ts", + "generated/oracle/instructions.cjs", + "generated/oracle/instructions.js", + "generated/oracle/instructions.d.ts", + "generated/oracle/types.cjs", + "generated/oracle/types.js", + "generated/oracle/types.d.ts", + "generated/attestation.cjs", + "generated/attestation.js", + "generated/attestation.d.ts", + "generated/attestation/accounts.cjs", + "generated/attestation/accounts.js", + "generated/attestation/accounts.d.ts", + "generated/attestation/instructions.cjs", + "generated/attestation/instructions.js", + "generated/attestation/instructions.d.ts", + "generated/attestation/types.cjs", + "generated/attestation/types.js", + "generated/attestation/types.d.ts" + ], + "scripts": { + "build": "node esbuild.js", + "clean": "pnpm exec rimraf node_modules lib .turbo", + "close-functions": "tsx ./scripts/close-functions.ts", + "fix": "pnpm exec eslint --fix src", + "generate": "tsx ./scripts/generate-client.ts", + "keypair:create": "pnpm exec shx find ~/.config/solana/id.json || solana-keygen new -s --no-bip39-passphrase --outfile ~/.config/solana/id.json", + "lint": "pnpm exec eslint src", + "local:validator": "shx mkdir -p .anchor/test-ledger || true; solana-test-validator -q -r --ledger .anchor/test-ledger --mint $(solana-keygen pubkey ~/.config/solana/id.json) --bind-address 0.0.0.0 --url https://api.devnet.solana.com --rpc-port 8899 --clone SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f `# programId` --clone 7nYabs9dUhvxYwdTnrWVBL9MYviKSfrEbdWCUbcnwkpF `# programDataAddress` --clone Fi8vncGpNKbq62gPo56G4toCehWNy77GgqGkTaAF5Lkk `# idlAddress` --clone sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx `# sgxProgramId` --clone BzqtGXZPiDSinP4xMFgPf6FLgSa6iPufK4m4JJFgMnTK `# sgxProgramDataAddress` --clone 5MFs7RGTjLi1wtKNBFRtuLipCkkjs4YQwRRU9sjnbQbS `# sgxProgramState` --clone 5ExuoQR69trmKQfB95fDsUGsUrrChbGq9PFgt8qouncz `# sgxIdlAddress` --clone CyZuD7RPDcrqCGbNvLCyqk6Py9cEZTKmNKujfPi3ynDd `# programState` --clone 7hkp1xfPBcD2t1vZMoWWQPzipHVcXeLAAaiGXdPSfDie `# switchboardVault`", + "local:validator:mainnet": "solana-test-validator -q -r --ledger .anchor/test-ledger --mint $(solana-keygen pubkey ~/.config/solana/id.json) --bind-address 0.0.0.0 --rpc-port 8899 --url https://api.mainnet-beta.solana.com --clone SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f --clone 7nYabs9dUhvxYwdTnrWVBL9MYviKSfrEbdWCUbcnwkpF --clone Fi8vncGpNKbq62gPo56G4toCehWNy77GgqGkTaAF5Lkk --clone sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx --clone BzqtGXZPiDSinP4xMFgPf6FLgSa6iPufK4m4JJFgMnTK --clone 5MFs7RGTjLi1wtKNBFRtuLipCkkjs4YQwRRU9sjnbQbS --clone 5ExuoQR69trmKQfB95fDsUGsUrrChbGq9PFgt8qouncz --clone CyZuD7RPDcrqCGbNvLCyqk6Py9cEZTKmNKujfPi3ynDd --clone J7nSEX8ADf3pVVicd6yKy2Skvg8iLePEmkLUisAAaioD", + "localnet": "tsx ./scripts/localnet.ts", + "localnet:down": "kill -9 $(pgrep command solana-test-validator) || exit 0", + "test": "node ./node_modules/mocha/bin/mocha --loader=ts-node/esm --extension ts --timeout 60000 --exit", + "test:localnet": "SOLANA_LOCALNET=1 node ./node_modules/mocha/bin/mocha --exit", + "test:localnet:mainnet": "SWITCHBOARD_PROGRAM_ID=SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f SOLANA_LOCALNET=1 SOLANA_CLUSTER=mainnet-beta node ./node_modules/mocha/bin/mocha --loader=ts-node/esm --extension ts --timeout 60000 --exit", + "watch": "pnpm exec tsc -p tsconfig.cjs.json --watch" + }, + "pre-commit": [ + "build" + ], + "dependencies": { + "@coral-xyz/anchor": "^0.28.0", + "@coral-xyz/borsh": "^0.28.0", + "@solana/spl-token": "^0.3.8", + "@solana/web3.js": "^1.78.3", + "@switchboard-xyz/common": "^", + "cron-validator": "^1.3.1", + "cross-fetch": "^4.0.0", + "dotenv": "^16.3.1", + "lodash": "^4.17.21", + "zod": "^3.22.2", + "zod-error": "^1.5.0" + }, + "devDependencies": { + "@switchboard-xyz/eslint-config": "latest", + "@switchboard-xyz/oracle": "latest", + "@types/chai": "^4.3.5", + "@types/lodash": "^4.14.195", + "@types/mocha": "^10.0.1", + "@types/shelljs": "^0.8.12", + "anchor-client-gen": "^0.28.1", + "chai": "^4.3.7", + "chalk": "^4.1.2", + "esbuild": "^0.17.19", + "mocha": "^10.2.0", + "shelljs": "^0.8.5", + "ts-mocha": "^10.0.0", + "ts-node": "^10.9.1", + "tsx": "^3.12.7", + "typedoc": "^0.23.28" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" } } diff --git a/javascript/solana.js/scripts/generate-client.ts b/javascript/solana.js/scripts/generate-client.ts index 336cbf0aa..43aa4c515 100644 --- a/javascript/solana.js/scripts/generate-client.ts +++ b/javascript/solana.js/scripts/generate-client.ts @@ -25,6 +25,10 @@ const attestationDevnetIdlPath = path.join( packageRoot, "./idl/attestation-devnet.json" ); +const attestationMainnetIdlPath = path.join( + packageRoot, + "./idl/attestation-mainnet.json" +); const attestationGeneratedPath = path.join( packageRoot, "./src/generated/attestation-program" @@ -51,6 +55,8 @@ const ignoreFiles = [ `${attestationGeneratedPath}/types/VerificationStatus.ts`, `${attestationGeneratedPath}/errors/index.ts`, `${attestationGeneratedPath}/types/SwitchboardAttestationPermission.ts`, + `${attestationGeneratedPath}/types/FunctionStatus.ts`, + `${attestationGeneratedPath}/types/index.ts`, // TODO: may need to comment out when adding new types and manually fix errors `${attestationGeneratedPath}/instructions/functionDeactivateLookup.ts`, `${attestationGeneratedPath}/instructions/accountCloseOverride.ts`, `${attestationGeneratedPath}/instructions/viewVersion.ts`, @@ -135,6 +141,12 @@ async function main() { encoding: "utf-8", } ), + runCommandAsync( + `anchor idl fetch -o ${attestationMainnetIdlPath} sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx --provider.cluster mainnet`, + { + encoding: "utf-8", + } + ), fsSync.existsSync(v2GeneratedPath) ? fs.rm(v2GeneratedPath, { recursive: true }) : Promise.resolve(), @@ -297,7 +309,7 @@ const processFile = async (file: string) => { ) // remove this import, using SwitchboardProgram .replace(`import { PROGRAM_ID } from "../programId"`, ``) - .replaceAll(`PROGRAM_ID`, `program.programId`) + .replaceAll(`PROGRAM_ID`, `program.oracleProgramId`) .replaceAll(`c: Connection,`, `program: SwitchboardProgram,`) .replaceAll(`c.getAccountInfo`, `program.connection.getAccountInfo`) .replaceAll( @@ -314,7 +326,7 @@ const processFile = async (file: string) => { if (file.includes("/attestation-program/")) { updatedFileString = updatedFileString.replaceAll( - `program.programId`, + `program.oracleProgramId`, `program.attestationProgramId` ); } diff --git a/javascript/solana.js/src/SwitchboardError.ts b/javascript/solana.js/src/SwitchboardError.ts index 3e26bac08..b6b6f98e5 100644 --- a/javascript/solana.js/src/SwitchboardError.ts +++ b/javascript/solana.js/src/SwitchboardError.ts @@ -11,8 +11,20 @@ export class SwitchboardError { * @param code Error code to convert to a SwitchboardError object. * @return SwitchboardError */ - static fromCode(program: SwitchboardProgram, code: number): SwitchboardError { - for (const e of program.idl.errors ?? []) { + static async fromCode( + program: SwitchboardProgram, + code: number + ): Promise { + const [oracleProgram, attestationProgram] = await Promise.all([ + program.oracleProgram, + program.attestationProgram, + ]); + const errors = [ + ...(oracleProgram.idl.errors ?? []), + ...(attestationProgram.idl.errors ?? []), + ]; + + for (const e of errors ?? []) { if (code === e.code) { return new SwitchboardError(program, e.name, e.code, e.msg); } diff --git a/javascript/solana.js/src/SwitchboardProgram.ts b/javascript/solana.js/src/SwitchboardProgram.ts index f0d8d1873..fb636386a 100644 --- a/javascript/solana.js/src/SwitchboardProgram.ts +++ b/javascript/solana.js/src/SwitchboardProgram.ts @@ -1,17 +1,17 @@ import type { + CrankAccount, + QueueAccount, SwitchboardAccountData, SwitchboardAccountType, } from "./accounts/index.js"; import { AttestationProgramStateAccount, BUFFER_DISCRIMINATOR, - CrankAccount, DISCRIMINATOR_MAP, JobAccount, ProgramStateAccount, - QueueAccount, } from "./accounts/index.js"; -import { viewVersion as viewAttestationVersion } from "./generated/attestation-program/instructions/viewVersion.js"; +import { viewVersion as viewAttestationProgramVersion } from "./generated/attestation-program/instructions/viewVersion.js"; import { AggregatorAccountData, BufferRelayerAccountData, @@ -25,7 +25,7 @@ import { SlidingResultAccountData, VrfAccountData, } from "./generated/index.js"; -import { viewVersion as viewSbVersion } from "./generated/oracle-program/instructions/viewVersion.js"; +import { viewVersion as viewOracleProgramVersion } from "./generated/oracle-program/instructions/viewVersion.js"; import { DEVNET_GENESIS_HASH, MAINNET_GENESIS_HASH, @@ -64,12 +64,8 @@ import type { Transaction, TransactionSignature, } from "@solana/web3.js"; -import { - Keypair, - PublicKey, - TransactionMessage, - VersionedTransaction, -} from "@solana/web3.js"; +import { VersionedTransaction } from "@solana/web3.js"; +import { Keypair, PublicKey, TransactionMessage } from "@solana/web3.js"; import { OracleJob } from "@switchboard-xyz/common"; export type SendTransactionOptions = (ConfirmOptions | SendOptions) & { @@ -161,14 +157,26 @@ export class SwitchboardProgram { // The read-only keypair for the Switchboard program. private static readonly _readOnlyKeypair = READ_ONLY_KEYPAIR; - // The anchor program instance. - private readonly _program: Program; + // // The anchor program instance. + // private readonly _program: Program; - // The anchor program instance for Switchboard's attestation program. - private readonly _attestationProgram: Program; + // // The anchor program instance for Switchboard's attestation program. + // private readonly _attestationProgram: Program; + + /** Lazy load */ + private _oracleProgram: Promise | undefined = undefined; + + /** Lazy load */ + private _attestationProgram: Promise | undefined = undefined; /** The Solana cluster to load the Switchboard program for. */ - readonly cluster: Cluster | "localnet"; + private _cluster: Promise | undefined = undefined; + + /** + * The anchor Provider used by this program to connect with the Solana cluster. + * @return The AnchorProvider instance for the Switchboard Program. + */ + public readonly provider: AnchorProvider; // The pubkey and bump of the Switchboard program state account. readonly programState: { @@ -185,57 +193,112 @@ export class SwitchboardProgram { // The native mint for the Switchboard program. readonly mint: NativeMint; + /** + * Retrieves the Switchboard V2 Program ID for the currently connected cluster. + * @return The PublicKey of the Switchboard V2 Program ID. + */ + public readonly oracleProgramId: PublicKey; + + /** + * Retrieves the Switchboard Attestation Program ID for the currently connected cluster. + * @return The PublicKey of the Switchboard Attestation Program ID. + */ + public readonly attestationProgramId: PublicKey; /** * Constructor for the SwitchboardProgram class. * - * @param program - The anchor program instance. - * @param cluster - The Solana cluster to load the Switchboard program for. + * @param provider - The AnchorProvider containing the RPC and wallet connection. * @param mint - The native mint for the Switchboard program. + * @param oracleProgramId - The Switchboard V2 Oracle Program ID. + * @param attestationProgramId - The Switchboard Attestation Program ID. */ constructor( - program: Program, - attestationProgram: Program, - cluster: Cluster | "localnet", - mint: NativeMint + provider: AnchorProvider, + mint: NativeMint = new NativeMint(provider), + oracleProgramId: PublicKey = SB_V2_PID, + attestationProgramId: PublicKey = SB_ATTESTATION_PID, + /** Lazy loading parameters to pass-through */ + oracleProgram?: Promise, + attestationProgram?: Promise ) { - this._program = program; - this._attestationProgram = attestationProgram; - this.cluster = cluster; + this.provider = provider; + this.mint = mint; + this.oracleProgramId = oracleProgramId; + this.attestationProgramId = attestationProgramId; + if (oracleProgram) { + this._oracleProgram = oracleProgram; + } + if (attestationProgram) { + this._attestationProgram = attestationProgram; + } // Derive the state account from the seed. - const stateAccount = ProgramStateAccount.fromSeed(this); + const [programStatePubkey, programStateBump] = + PublicKey.findProgramAddressSync([Buffer.from("STATE")], oracleProgramId); this.programState = { - publicKey: stateAccount[0].publicKey, - bump: stateAccount[1], + publicKey: programStatePubkey, + bump: programStateBump, }; - this.programState = { - publicKey: stateAccount[0].publicKey, - bump: stateAccount[1], + const [attestationProgramStatePubkey, attestationProgramStateBump] = + PublicKey.findProgramAddressSync( + [Buffer.from("STATE")], + attestationProgramId + ); + this.attestationProgramState = { + publicKey: attestationProgramStatePubkey, + bump: attestationProgramStateBump, }; + } - // TODO: produce the attestation state account from the seed. - if (this._attestationProgram) { - const attestationStateAccount = - AttestationProgramStateAccount.fromSeed(this); - this.attestationProgramState = { - publicKey: attestationStateAccount[0].publicKey, - bump: attestationStateAccount[1], - }; - } else { - const [attestationProgramStatePubkey, attestationProgramStateBump] = - PublicKey.findProgramAddressSync( - [Buffer.from("STATE")], - SB_ATTESTATION_PID - ); - - this.attestationProgramState = { - publicKey: attestationProgramStatePubkey, - bump: attestationProgramStateBump, - }; - } - - this.mint = mint; + /** + * Create and initialize a {@linkcode SwitchboardProgram} connection object. + * + * @dev This method is synchronous but will return a promise for consistency with past be. + * + * @param connection - the Solana connection object used to connect to an RPC node. + * + * @param payerKeypair - optional, payer keypair used to pay for on-chain transactions. + * + * @param oracleProgramId - optional, override the default oracleProgramId. + * + * @param attestationProgramId - optional, override the default attestationProgramId. + * + * @return the {@linkcode SwitchboardProgram} used to create and interact with Switchboard accounts. + * + * Basic usage example: + * + * ```ts + * import { Connection } from "@solana/web3.js"; + * import { SwitchboardProgram, TransactionObject } from '@switchboard-xyz/solana.js'; + * + * const program = SwitchboardProgram.from( + * new Connection("https://api.mainnet-beta.solana.com"), + * payerKeypair + * ); + * + * const txn = new TransactionObject(program.walletPubkey, [], []); + * const txnSignature = await program.signAndSend(txn); + * ``` + */ + public static from( + connection: Connection, + payerKeypair = READ_ONLY_KEYPAIR, + oracleProgramId = SB_V2_PID, + attestationProgramId = SB_ATTESTATION_PID + ): SwitchboardProgram { + const provider = new AnchorProvider( + connection, + new AnchorWallet(payerKeypair), + {} + ); + const mint = new NativeMint(provider); + return new SwitchboardProgram( + provider, + mint, + oracleProgramId, + attestationProgramId + ); } /** @@ -244,31 +307,28 @@ export class SwitchboardProgram { * This method fetches the IDL for the Switchboard program, and initializes an anchor program * instance using the fetched IDL, provided program ID, and provider. * - * @param cluster - The Solana cluster to load the Switchboard program for. * @param connection - The Solana connection object used to connect to an RPC node. + * @param programId - The programID to load the Anchor program for. The program must have an IDL deployed. * @param payerKeypair - Optional payer keypair used to pay for on-chain transactions. - * @param programId - Optional program ID to override the cluster's default programId. * - * @returns The initialized anchor program instance for the Switchboard. + * @returns The initialized anchor program instance. */ static async loadAnchorProgram( - cluster: Cluster | "localnet", connection: Connection, - payerKeypair: Keypair = READ_ONLY_KEYPAIR, - programId?: PublicKey + programId: PublicKey, + payerKeypair: Keypair = READ_ONLY_KEYPAIR ): Promise { - const pid = programId ?? getSwitchboardProgramId(cluster); const provider = new AnchorProvider( connection, // If no keypair is provided, default to dummy keypair new AnchorWallet(payerKeypair ?? SwitchboardProgram._readOnlyKeypair), { commitment: "confirmed" } ); - const anchorIdl = await Program.fetchIdl(pid, provider); + const anchorIdl = await Program.fetchIdl(programId, provider); if (!anchorIdl) { - throw new Error(`Failed to find IDL for ${pid.toBase58()}`); + throw new Error(`Failed to find IDL for ${programId.toBase58()}`); } - const program = new Program(anchorIdl, pid, provider); + const program = new Program(anchorIdl, programId, provider); return program; } @@ -276,13 +336,11 @@ export class SwitchboardProgram { /** * Create and initialize a {@linkcode SwitchboardProgram} connection object. * - * @param cluster - the solana cluster to load the Switchboard program for. + * @dev This method is synchronous but will return a promise for consistency with past be. * * @param connection - the Solana connection object used to connect to an RPC node. - * * @param payerKeypair - optional, payer keypair used to pay for on-chain transactions. - * - * @param programId - optional, override the cluster's default programId. + * @param oracleProgramId - optional, override the cluster's default oracleProgramId. * * @return the {@linkcode SwitchboardProgram} used to create and interact with Switchboard accounts. * @@ -293,7 +351,6 @@ export class SwitchboardProgram { * import { SwitchboardProgram, TransactionObject } from '@switchboard-xyz/solana.js'; * * const program = await SwitchboardProgram.load( - * "mainnet-beta", * new Connection("https://api.mainnet-beta.solana.com"), * payerKeypair * ); @@ -303,39 +360,30 @@ export class SwitchboardProgram { * ``` */ static load = async ( - cluster: Cluster | "localnet", connection: Connection, payerKeypair = READ_ONLY_KEYPAIR, - programId = getSwitchboardProgramId(cluster), - attestationProgramId = getSwitchboardAttestationProgramId(cluster) + oracleProgramId = SB_V2_PID, + attestationProgramId = SB_ATTESTATION_PID ): Promise => { - const [program, attestationProgram] = await Promise.all([ - SwitchboardProgram.loadAnchorProgram( - cluster, - connection, - payerKeypair, - programId - ), - SwitchboardProgram.loadAnchorProgram( - cluster, - connection, - payerKeypair, - attestationProgramId - ), - ]); - const mint = await NativeMint.load(program.provider as AnchorProvider); - return new SwitchboardProgram(program, attestationProgram, cluster, mint); + const provider = new AnchorProvider( + connection, + new AnchorWallet(payerKeypair), + {} + ); + const mint = new NativeMint(provider); + return new SwitchboardProgram( + provider, + mint, + oracleProgramId, + attestationProgramId + ); }; - // public verifyAttestation(): void { - // if (this._attestationProgram === undefined) { - // throw new Error(`Attestation Program is missing`); - // } - // } - /** * Create and initialize a {@linkcode SwitchboardProgram} connection object. * + * @dev This method is synchronous but will return a promise for consistency with past behavior. + * * @param provider - The anchor provider containing the RPC and wallet connection. * * @return The {@linkcode SwitchboardProgram} used to create and interact with Switchboard accounts. @@ -361,25 +409,26 @@ export class SwitchboardProgram { */ static fromProvider = async ( provider: AnchorProvider, - programId?: PublicKey, - attestationProgramId?: PublicKey + oracleProgramId: PublicKey = SB_V2_PID, + attestationProgramId: PublicKey = SB_ATTESTATION_PID ): Promise => { - const payer = (provider.wallet as AnchorWallet).payer; - const program = await SwitchboardProgram.fromConnection( - provider.connection, - payer, - programId, + const mint = new NativeMint(provider); + return new SwitchboardProgram( + provider, + mint, + oracleProgramId, attestationProgramId ); - return program; }; /** * Create and initialize a {@linkcode SwitchboardProgram} connection object. * + * @dev This method is synchronous but will return a promise for consistency with past behavior. + * * @param connection - The Solana connection object used to connect to an RPC node. * @param payer - Optional, payer keypair used to pay for on-chain transactions (defaults to READ_ONLY_KEYPAIR). - * @param programId - Optional, override the cluster's default programId. + * @param oracleProgramId - Optional, override the cluster's default oracleProgramId. * * @return The {@linkcode SwitchboardProgram} instance used to create and interact with Switchboard accounts. * @@ -397,50 +446,105 @@ export class SwitchboardProgram { static fromConnection = async ( connection: Connection, payer = READ_ONLY_KEYPAIR, - programId?: PublicKey, - attestationProgramId?: PublicKey + oracleProgramId: PublicKey = SB_V2_PID, + attestationProgramId: PublicKey = SB_ATTESTATION_PID ): Promise => { - const genesisHash = await connection.getGenesisHash(); - const cluster = - genesisHash === MAINNET_GENESIS_HASH - ? "mainnet-beta" - : genesisHash === DEVNET_GENESIS_HASH - ? "devnet" - : "localnet"; - - const pid = programId ?? SB_V2_PID; - const programAccountInfo = await connection.getAccountInfo(pid); - if (programAccountInfo === null) { - throw new Error( - `Failed to load Switchboard V2 program at ${pid}, try manually providing a programId` - ); + const program = await SwitchboardProgram.load( + connection, + payer, + oracleProgramId, + attestationProgramId + ); + return program; + }; + + public get cluster(): Promise | "localnet"> { + if (!this._cluster) { + this._cluster = this.connection + .getGenesisHash() + .then((genesisHash) => { + switch (genesisHash) { + case MAINNET_GENESIS_HASH: + return "mainnet-beta"; + case DEVNET_GENESIS_HASH: + return "devnet"; + default: + return "localnet"; + } + }) + .catch((err) => { + console.error(err); + this._cluster = undefined; + throw err; + }); } - const attestationPid = attestationProgramId ?? SB_ATTESTATION_PID; - const attestationProgramAccountInfo = await connection.getAccountInfo( - attestationPid + return this._cluster; + } + + public get oracleProgram(): Promise { + if (!this._oracleProgram) { + this._oracleProgram = this.getOracleProgram().catch((err) => { + console.error(err); + this._oracleProgram = undefined; + throw err; + }); + } + return this._oracleProgram; + } + + private async getOracleProgram(retryCount = 3): Promise { + const anchorIdl = await Program.fetchIdl( + this.oracleProgramId, + this.provider ); - if (attestationProgramAccountInfo === null) { + if (!anchorIdl) { throw new Error( - `Failed to load Switchboard Attestation program at ${attestationPid}, try manually providing a programId` + `Failed to find IDL for ${this.oracleProgramId.toBase58()}` ); } + return new Program(anchorIdl, this.oracleProgramId, this.provider); + } - const program = await SwitchboardProgram.load( - cluster, - connection, - payer, - pid, - attestationPid - ); - return program; - }; + public get attestationProgram(): Promise { + if (!this._attestationProgram) { + this._attestationProgram = this.getAttestationProgram().catch((err) => { + console.error(err); + this._attestationProgram = undefined; + throw err; + }); + } + return this._attestationProgram; + } + + private async getAttestationProgram(retryCount = 3): Promise { + try { + const anchorIdl = await Program.fetchIdl( + this.attestationProgramId, + this.provider + ); + if (!anchorIdl) { + throw new Error( + `Failed to find IDL for ${this.attestationProgramId.toBase58()}` + ); + } + return new Program(anchorIdl, this.attestationProgramId, this.provider); + } catch (error) { + if (0 >= retryCount) { + throw error; + } + return this.getAttestationProgram(retryCount - 1); + } + } public async getGitVersion(): Promise { const messageV0 = new TransactionMessage({ payerKey: this.walletPubkey, instructions: [ - await this._program.methods.viewVersion().accounts({}).instruction(), + await (await this.oracleProgram).methods + .viewVersion() + .accounts({}) + .instruction(), ], recentBlockhash: (await this.connection.getLatestBlockhash()).blockhash, }).compileToLegacyMessage(); @@ -453,6 +557,7 @@ export class SwitchboardProgram { if (version) { return version; } + console.error(logs); throw new Error( `Failed to yield the git version in the view_version simulation result` ); @@ -462,7 +567,7 @@ export class SwitchboardProgram { const messageV0 = new TransactionMessage({ payerKey: this.walletPubkey, instructions: [ - await this._attestationProgram.methods + await (await this.attestationProgram).methods .viewVersion() .accounts({}) .instruction(), @@ -473,70 +578,32 @@ export class SwitchboardProgram { new VersionedTransaction(messageV0), { sigVerify: false } ); + console.error(simulationResult); const logs = (simulationResult.value?.logs ?? []).join("\n"); const version = extractVersion(logs); if (version) { return version; } + console.error(logs); throw new Error( `Failed to yield the git version in the view_version simulation result` ); } - /** - * Retrieves the Switchboard V2 Program ID for the currently connected cluster. - * @return The PublicKey of the Switchboard V2 Program ID. - */ - public get programId(): PublicKey { - return this._program.programId; - } - - /** - * Retrieves the Switchboard Attestation Program ID for the currently connected cluster. - * @return The PublicKey of the Switchboard Attestation Program ID. - */ - public get attestationProgramId(): PublicKey { - return this._attestationProgram.programId; - } - /** * Retrieves the Switchboard V2 Program IDL. - * @return The IDL of the Switchboard V2 Program. + * @return A promise that resolves to the IDL of the Switchboard V2 Program. */ - public get idl(): Idl { - return this._program.idl; + public get oracleProgramIdl(): Promise { + return this.oracleProgram.then((program) => program.idl); } /** * Retrieves the Switchboard Attestation Program IDL. - * @return The IDL of the Switchboard Attestation Program. - */ - public get attestationIdl(): Idl { - return this._program.idl; - } - - /** - * Retrieves the Switchboard V2 Borsh Accounts Coder. - * @return The BorshAccountsCoder for the Switchboard V2 Program. + * @return A promise that resolves to the IDL of the Switchboard Attestation Program. */ - public get coder(): BorshAccountsCoder { - return new BorshAccountsCoder(this._program.idl); - } - - /** - * Retrieves the Switchboard Attestatio Borsh Accounts Coder. - * @return The BorshAccountsCoder for the Switchboard Attestation Program. - */ - public get attestationCoder(): BorshAccountsCoder { - return new BorshAccountsCoder(this._attestationProgram.idl); - } - - /** - * Retrieves the anchor Provider used by this program to connect with the Solana cluster. - * @return The AnchorProvider instance for the Switchboard Program. - */ - public get provider(): AnchorProvider { - return this._program.provider as AnchorProvider; + public get attestationIdl(): Promise { + return this.attestationProgram.then((program) => program.idl); } /** @@ -573,21 +640,13 @@ export class SwitchboardProgram { new AnchorWallet(payer), this.provider.opts ); - const program = new Program( - this._program.idl, - this._program.programId, - newProvider - ); - const attestationProgram = new Program( - this._attestationProgram.idl, - this._attestationProgram.programId, - newProvider - ); return new SwitchboardProgram( - program, - attestationProgram, - this.cluster, - this.mint + newProvider, + this.mint, + this.oracleProgramId, + this.attestationProgramId, + this._oracleProgram, + this._attestationProgram ); } @@ -650,16 +709,16 @@ export class SwitchboardProgram { * Retrieves the account namespace for the Switchboard V2 Program. * @return The AccountNamespace instance for the Switchboard V2 Program. */ - public get account(): AccountNamespace { - return this._program.account; + public get oracleProgramAccount(): Promise { + return this.oracleProgram.then((program) => program.account); } /** * Retrieves the account namespace for the Switchboard Attestation Program. * @return The AccountNamespace instance for the Switchboard Attestation Program. */ - public get attestationAccount(): AccountNamespace { - return this._attestationProgram.account; + public get attestationAccount(): Promise { + return this.attestationProgram.then((program) => program.account); } /** @@ -676,33 +735,8 @@ export class SwitchboardProgram { crankAccount: CrankAccount; crank: CrankAccountData; }> { - const queueKey = - this.cluster === "mainnet-beta" - ? SWITCHBOARD_LABS_MAINNET_PERMISSIONLESS_QUEUE - : this.cluster === "devnet" - ? SWITCHBOARD_LABS_DEVNET_PERMISSIONLESS_QUEUE - : null; - if (!queueKey) { - throw new Error( - `Failed to load the permissionless queue for cluster ${this.cluster}` - ); - } - const [queueAccount, queue] = await QueueAccount.load(this, queueKey); - - const crankKey = - this.cluster === "mainnet-beta" - ? SWITCHBOARD_LABS_MAINNET_PERMISSIONLESS_CRANK - : this.cluster === "devnet" - ? SWITCHBOARD_LABS_DEVNET_PERMISSIONLESS_CRANK - : null; - if (!crankKey) { - throw new Error( - `Failed to load the permissionless queue for cluster ${this.cluster}` - ); - } - const [crankAccount, crank] = await CrankAccount.load(this, crankKey); - - return { queueAccount, queue, crankAccount, crank }; + // TODO: make this load from common network configs + throw new Error(`Not implemented yet`); } /** @@ -719,38 +753,8 @@ export class SwitchboardProgram { crankAccount: CrankAccount; crank: CrankAccountData; }> { - const queueKey = - this.cluster === "mainnet-beta" - ? SWITCHBOARD_LABS_MAINNET_PERMISSIONED_QUEUE - : this.cluster === "devnet" - ? SWITCHBOARD_LABS_DEVNET_PERMISSIONED_QUEUE - : null; - if (!queueKey) { - throw new Error( - `Failed to load the permissioned queue for cluster ${this.cluster}` - ); - } - const [queueAccount, queue] = await QueueAccount.load( - this, - this.cluster === "mainnet-beta" - ? SWITCHBOARD_LABS_MAINNET_PERMISSIONED_QUEUE - : SWITCHBOARD_LABS_DEVNET_PERMISSIONED_QUEUE - ); - - const crankKey = - this.cluster === "mainnet-beta" - ? SWITCHBOARD_LABS_MAINNET_PERMISSIONED_CRANK - : this.cluster === "devnet" - ? SWITCHBOARD_LABS_DEVNET_PERMISSIONED_CRANK - : null; - if (!crankKey) { - throw new Error( - `Failed to load the permissionless queue for cluster ${this.cluster}` - ); - } - const [crankAccount, crank] = await CrankAccount.load(this, crankKey); - - return { queueAccount, queue, crankAccount, crank }; + // TODO: make this load from common network configs + throw new Error(`Not implemented yet`); } /** @@ -761,15 +765,18 @@ export class SwitchboardProgram { * @param callback - A callback function to handle the event data, slot, and signature. * @return A unique listener ID that can be used to remove the event listener. */ - public addEventListener( + public async addEventListener( eventName: EventName, callback: ( data: SwitchboardEvents[EventName], slot: number, signature: string ) => void | Promise - ): number { - return this._program.addEventListener(eventName as string, callback); + ): Promise { + return (await this.oracleProgram).addEventListener( + eventName as string, + callback + ); } /** @@ -778,7 +785,7 @@ export class SwitchboardProgram { * @param listenerId - The unique ID of the event listener to be removed. */ public async removeEventListener(listenerId: number) { - return await this._program.removeEventListener(listenerId); + return await (await this.oracleProgram).removeEventListener(listenerId); } /** @@ -789,15 +796,17 @@ export class SwitchboardProgram { * @param callback - A callback function to handle the event data, slot, and signature. * @return A unique listener ID that can be used to remove the event listener. */ - public addAttestationEventListener( + public async addAttestationEventListener< + EventName extends keyof SwitchboardEvents + >( eventName: EventName, callback: ( data: SwitchboardEvents[EventName], slot: number, signature: string ) => void | Promise - ): number { - return this._attestationProgram.addEventListener( + ): Promise { + return (await this.attestationProgram).addEventListener( eventName as string, callback ); @@ -809,7 +818,9 @@ export class SwitchboardProgram { * @param listenerId - The unique ID of the event listener to be removed. */ public async removeAttestationEventListener(listenerId: number) { - return await this._attestationProgram.removeEventListener(listenerId); + return await ( + await this.attestationProgram + ).removeEventListener(listenerId); } public async signAndSendAll( @@ -839,7 +850,7 @@ export class SwitchboardProgram { async getProgramJobAccounts(): Promise> { const accountInfos = await this.connection - .getProgramAccounts(this.programId, { + .getProgramAccounts(this.oracleProgramId, { filters: [ { memcmp: { @@ -892,7 +903,7 @@ export class SwitchboardProgram { vrfs: Map; }> { const accountInfos: GetProgramAccountsResponse = - await this.connection.getProgramAccounts(this.programId); + await this.connection.getProgramAccounts(this.oracleProgramId); // buffer - [42, 55, 46, 46, 45, 52, 78, 78] // bufferRelayer - [50, 35, 51, 115, 169, 219, 158, 52] diff --git a/javascript/solana.js/src/accounts/account.ts b/javascript/solana.js/src/accounts/account.ts index 293280955..7d73b87b0 100644 --- a/javascript/solana.js/src/accounts/account.ts +++ b/javascript/solana.js/src/accounts/account.ts @@ -47,11 +47,6 @@ export abstract class Account { : publicKey; } - /** - * @return on-chain account size. - */ - public abstract get size(): number; - /** * Retrieve and decode the data in this account. */ diff --git a/javascript/solana.js/src/accounts/aggregatorAccount.ts b/javascript/solana.js/src/accounts/aggregatorAccount.ts index 60a0a9bd8..f942fa10c 100644 --- a/javascript/solana.js/src/accounts/aggregatorAccount.ts +++ b/javascript/solana.js/src/accounts/aggregatorAccount.ts @@ -108,17 +108,10 @@ export class AggregatorAccount extends Account { /** * Get the size of an {@linkcode AggregatorAccount} on-chain. */ - public size = this.program.account.aggregatorAccountData.size; + public size = 3851; public decode(data: Buffer): AggregatorAccountData { - try { - return AggregatorAccountData.decode(data); - } catch { - return this.program.coder.decode( - AggregatorAccount.accountName, - data - ); - } + return AggregatorAccountData.decode(data); } /** @@ -197,7 +190,7 @@ export class AggregatorAccount extends Account { public get slidingWindowKey(): PublicKey { return PublicKey.findProgramAddressSync( [Buffer.from("SlidingResultAccountData"), this.publicKey.toBytes()], - this.program.programId + this.program.oracleProgramId )[0]; } @@ -266,11 +259,11 @@ export class AggregatorAccount extends Account { SystemProgram.createAccount({ fromPubkey: payer, newAccountPubkey: keypair.publicKey, - space: program.account.aggregatorAccountData.size, + space: AggregatorAccount.size, lamports: await program.connection.getMinimumBalanceForRentExemption( - program.account.aggregatorAccountData.size + AggregatorAccount.size ), - programId: program.programId, + programId: program.oracleProgramId, }) ); @@ -984,17 +977,14 @@ export class AggregatorAccount extends Account { `Failed to fetch account data for job ${j?.publicKey}` ); } - if (!j.account.owner.equals(this.program.programId)) { + if (!j.account.owner.equals(this.program.oracleProgramId)) { throw new errors.IncorrectOwner( - this.program.programId, + this.program.oracleProgramId, j.account.owner ); } const jobAccount = new JobAccount(this.program, j.publicKey); - const jobState: JobAccountData = this.program.coder.decode( - "JobAccountData", - j.account.data - ); + const jobState: JobAccountData = JobAccountData.decode(j.account.data); return { account: jobAccount, state: jobState, @@ -2425,7 +2415,7 @@ export class AggregatorAccount extends Account { }, opts?: TransactionObjectOptions ): Promise { - if (this.program.cluster === "mainnet-beta") { + if ((await this.program.cluster) === "mainnet-beta") { throw new Error( `Aggregators can only be closed with the devnet version of Switchboard` ); diff --git a/javascript/solana.js/src/accounts/aggregatorHistoryBuffer.ts b/javascript/solana.js/src/accounts/aggregatorHistoryBuffer.ts index 96dec630e..3653921d1 100644 --- a/javascript/solana.js/src/accounts/aggregatorHistoryBuffer.ts +++ b/javascript/solana.js/src/accounts/aggregatorHistoryBuffer.ts @@ -261,7 +261,7 @@ export class AggregatorHistoryBuffer extends Account< lamports: await program.connection.getMinimumBalanceForRentExemption( size ), - programId: program.programId, + programId: program.oracleProgramId, }), types.aggregatorSetHistoryBuffer( program, diff --git a/javascript/solana.js/src/accounts/attestationPermissionAccount.ts b/javascript/solana.js/src/accounts/attestationPermissionAccount.ts index 65b1eec48..9b2efbffd 100644 --- a/javascript/solana.js/src/accounts/attestationPermissionAccount.ts +++ b/javascript/solana.js/src/accounts/attestationPermissionAccount.ts @@ -142,12 +142,6 @@ export class AttestationPermissionAccount extends Account { static accountName = "AttestationQueueAccountData"; - /** - * Get the size of an {@linkcode types.AttestationQueueAccountData} on-chain. - */ - public readonly size = - this.program.attestationAccount.attestationQueueAccountData.size; - /** * Retrieve and decode the {@linkcode types.AttestationQueueAccountData} stored in this account. */ @@ -333,11 +324,11 @@ export class AttestationQueueAccount extends Account { + ): TransactionObject { const authority = params.authority?.publicKey ?? payer; const signers = params.authority ? [params.authority] : []; const instruction = types.attestationQueueAddMrEnclave( @@ -354,18 +345,17 @@ export class AttestationQueueAccount extends Account { - return await this.addMrEnclaveInstruction( - this.program.walletPubkey, - params, + return await this.program.signAndSend( + this.addMrEnclaveInstruction(this.program.walletPubkey, params, options), options - ).then((txn) => this.program.signAndSend(txn, options)); + ); } - public async removeMrEnclaveInstruction( + public removeMrEnclaveInstruction( payer: PublicKey, params: AttestationQueueRemoveMrEnclaveParams, options?: TransactionObjectOptions - ): Promise { + ): TransactionObject { const authority = params.authority?.publicKey ?? payer; const signers = params.authority ? [params.authority] : []; const instruction = types.attestationQueueRemoveMrEnclave( @@ -382,11 +372,14 @@ export class AttestationQueueAccount extends Account { - return await this.removeMrEnclaveInstruction( - this.program.walletPubkey, - params, + return await this.program.signAndSend( + this.removeMrEnclaveInstruction( + this.program.walletPubkey, + params, + options + ), options - ).then((txn) => this.program.signAndSend(txn, options)); + ); } /** @@ -586,8 +579,44 @@ export class AttestationQueueAccount extends Account { + const attestationQueue = _attestationQueue ?? (await this.loadData()); + const verifierPubkeys = attestationQueue.data.slice( + 0, + attestationQueue.dataLen + ); + if (verifierPubkeys.length === 0) { + return []; + } + + const data: VerifierAccountAndState[] = []; + + const accounts = await anchor.utils.rpc.getMultipleAccounts( + this.program.provider.connection, + verifierPubkeys + ); + + for (const account of accounts) { + if (!account) continue; + + data.push({ + publicKey: account.publicKey, + state: types.VerifierAccountData.decode(account.account.data), + }); + } + + return data; + } } +type VerifierAccountAndState = { + publicKey: PublicKey; + state: types.VerifierAccountData; +}; + export type CreateBootstrappedQueueParams = AttestationQueueAccountInitParams & { verifierEnclave: RawBuffer; diff --git a/javascript/solana.js/src/accounts/bufferRelayAccount.ts b/javascript/solana.js/src/accounts/bufferRelayAccount.ts index f5b5909be..625ae2ddf 100644 --- a/javascript/solana.js/src/accounts/bufferRelayAccount.ts +++ b/javascript/solana.js/src/accounts/bufferRelayAccount.ts @@ -40,22 +40,8 @@ import { BN, promiseWithTimeout } from "@switchboard-xyz/common"; export class BufferRelayerAccount extends Account { static accountName = "BufferRelayerAccountData"; - /** - * Returns the size of an on-chain {@linkcode BufferRelayerAccount}. - */ - public get size(): number { - return this.program.account.bufferRelayerAccountData.size; - } - public decode(data: Buffer): types.BufferRelayerAccountData { - try { - return types.BufferRelayerAccountData.decode(data); - } catch { - return this.program.coder.decode( - BufferRelayerAccount.accountName, - data - ); - } + return types.BufferRelayerAccountData.decode(data); } /** @@ -132,7 +118,7 @@ export class BufferRelayerAccount extends Account { /** The public key of the crank's data buffer storing a priority queue of {@linkcode AggregatorAccount}'s and their next available update timestamp */ dataBuffer?: CrankDataBuffer; - /** - * Get the size of an {@linkcode CrankAccount} on-chain. - */ - public size = this.program.account.crankAccountData.size; - /** * Return a crank account initialized to the default values. */ @@ -123,7 +117,7 @@ export class CrankAccount extends Account { lamports: await program.connection.getMinimumBalanceForRentExemption( crankSize ), - programId: program.programId, + programId: program.oracleProgramId, }), types.crankInit( program, diff --git a/javascript/solana.js/src/accounts/functionAccount.ts b/javascript/solana.js/src/accounts/functionAccount.ts index 12c8dd0a4..ce32a451f 100644 --- a/javascript/solana.js/src/accounts/functionAccount.ts +++ b/javascript/solana.js/src/accounts/functionAccount.ts @@ -18,6 +18,7 @@ import { import type { FunctionRequestAccountInitParams, + FunctionRoutineAccountInitParams, SwitchboardWalletFundParams, VerifierAccount, } from "./index.js"; @@ -25,6 +26,7 @@ import { AttestationPermissionAccount, AttestationQueueAccount, FunctionRequestAccount, + FunctionRoutineAccount, SwitchboardWallet, } from "./index.js"; @@ -66,20 +68,29 @@ export type FunctionAccountInitSeeds = { * Parameters for initializing a {@linkcode FunctionAccount} */ export type FunctionAccountInitParams = FunctionAccountInitSeeds & { + // Metadata Config name?: string; metadata?: string; + + // Container Config container: string; version?: string; containerRegistry?: ContainerRegistryType; - schedule?: string; - mrEnclave?: Buffer | Uint8Array | number[]; - attestationQueue: AttestationQueueAccount; + // Request Config requestsDisabled?: boolean; requestsRequireAuthorization?: boolean; requestsFee?: number; + // Routines Config + routinesDisabled?: boolean; + routinesRequireAuthorization?: boolean; + routinesFee?: number; + + // Accounts + attestationQueue: AttestationQueueAccount; + /** * An authority to be used to control this account. * @@ -179,7 +190,12 @@ export interface FunctionTriggerParams { export type CreateFunctionRequestParams = Omit< FunctionRequestAccountInitParams, "functionAccount" -> & { user?: Keypair }; +> & { keypair?: Keypair }; + +export type CreateFunctionRoutineParams = Omit< + FunctionRoutineAccountInitParams, + "functionAccount" +> & { keypair?: Keypair }; /** * Account type representing a Switchboard Function. @@ -203,12 +219,6 @@ export class FunctionAccount extends Account { public static getMetadata = (functionState: types.FunctionAccountData) => toUtf8(functionState.metadata); - /** - * Get the size of an {@linkcode FunctionAccount} on-chain. - */ - public readonly size = - this.program.attestationAccount.functionAccountData.size; - public get wallet(): Promise { if (!this._wallet) { this._wallet = this.loadData().then((fnState) => { @@ -327,10 +337,6 @@ export class FunctionAccount extends Account { ): Promise<[FunctionAccount, TransactionObject]> { const authorityPubkey = params.authority ?? payer; - const cronSchedule: Buffer = params.schedule - ? Buffer.from(parseCronSchedule(params.schedule), "utf-8") - : Buffer.from(Array(64).fill(0)); - const attestationQueueAccount = params.attestationQueue; const recentSlot: BN = params.recentSlot @@ -387,8 +393,15 @@ export class FunctionAccount extends Account { program, { params: { + // PDA Config + recentSlot: recentSlot, + creatorSeed: Array.from(creatorSeed), + + // Metadata Config name: new Uint8Array(Buffer.from(params.name ?? "", "utf8")), metadata: new Uint8Array(Buffer.from(params.metadata ?? "", "utf8")), + + // Container Config container: new Uint8Array(Buffer.from(params.container, "utf8")), containerRegistry: new Uint8Array( Buffer.from(params.containerRegistry ?? "dockerhub", "utf8") @@ -396,16 +409,20 @@ export class FunctionAccount extends Account { version: new Uint8Array( Buffer.from(params.version ?? "latest", "utf8") ), - schedule: new Uint8Array(cronSchedule), mrEnclave: Array.from( params.mrEnclave ? parseRawMrEnclave(params.mrEnclave) : [] ), - recentSlot: recentSlot, + + // Requests Config requestsDisabled: params.requestsDisabled ?? false, requestsRequireAuthorization: params.requestsRequireAuthorization ?? false, - requestsFee: numToBN(params.requestsFee), - creatorSeed: Array.from(creatorSeed), + requestsDevFee: numToBN(params.requestsFee), + + // Routines Config + routinesDisabled: false, + routinesDevFee: new BN(0), + routinesRequireAuthorization: false, }, }, { @@ -414,9 +431,9 @@ export class FunctionAccount extends Account { authority: authorityPubkey, attestationQueue: attestationQueueAccount.publicKey, payer, - wallet: escrowWallet.publicKey, - walletAuthority: escrowWalletAuthority, - tokenWallet: escrowWallet.tokenWallet, + escrowWallet: escrowWallet.publicKey, + escrowWalletAuthority: escrowWalletAuthority, + escrowTokenWallet: escrowWallet.tokenWallet, mint: program.mint.address, tokenProgram: TOKEN_PROGRAM_ID, associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, @@ -494,6 +511,42 @@ export class FunctionAccount extends Account { return [account, txSignature]; } + public async createRoutineInstruction( + payer: PublicKey, + params: CreateFunctionRoutineParams, + wallet?: SwitchboardWallet, + options?: TransactionObjectOptions + ): Promise<[FunctionRoutineAccount, TransactionObject]> { + const [routineAccount, txnObject] = + await FunctionRoutineAccount.createInstruction( + this.program, + payer, + { + ...params, + functionAccount: this, + }, + wallet, + options + ); + + return [routineAccount, txnObject]; + } + + public async createRoutine( + params: CreateFunctionRoutineParams, + wallet?: SwitchboardWallet, + options?: SendTransactionObjectOptions + ): Promise<[FunctionRoutineAccount, TransactionSignature]> { + const [account, txnObject] = await this.createRoutineInstruction( + this.program.walletPubkey, + params, + wallet, + options + ); + const txSignature = await this.program.signAndSend(txnObject, options); + return [account, txSignature]; + } + public async setConfigInstruction( payer: PublicKey, params: FunctionSetConfigParams, @@ -522,21 +575,33 @@ export class FunctionAccount extends Account { this.program, { params: { + // Metadata Config name: toOptionalBytes(params.name), metadata: toOptionalBytes(params.metadata), + + // Container Config container: toOptionalBytes(params.container), containerRegistry: toOptionalBytes(params.containerRegistry), version: toOptionalBytes(params.version), - schedule: toOptionalBytes(params.schedule), mrEnclaves: params.mrEnclaves ? params.mrEnclaves.map((mrEnclave) => Array.from(parseRawBuffer(mrEnclave)) ) : null, + + // Requests Config requestsDisabled: params.requestsDisabled ?? null, requestsRequireAuthorization: params.requestsRequireAuthorization ?? null, - requestsFee: params.requestsFee ? new BN(params.requestsFee) : null, + requestsDevFee: params.requestsFee + ? new BN(params.requestsFee) + : null, + + // Routines Config + routinesDisabled: null, + lockRoutinesDisabled: null, + routinesDevFee: null, + routinesRequireAuthorization: null, }, }, { @@ -622,16 +687,26 @@ export class FunctionAccount extends Account { this.program, { params: { + // Metadata Config name: null, metadata: null, + + // Container Config container: null, containerRegistry: null, version: null, - schedule: null, mrEnclaves: newMrEnclaves, + + // Requests Config requestsDisabled: null, requestsRequireAuthorization: null, - requestsFee: null, + requestsDevFee: null, + + // Routines Config + routinesDisabled: null, + lockRoutinesDisabled: null, + routinesDevFee: null, + routinesRequireAuthorization: null, }, }, { @@ -983,7 +1058,7 @@ export class FunctionAccount extends Account { params: { observedTime: params.observedTime, nextAllowedTimestamp: params.nextAllowedTimestamp, - isFailure: params.isFailure, + errorCode: params.isFailure ? 1 : 0, mrEnclave: Array.from(params.mrEnclave), }, }, diff --git a/javascript/solana.js/src/accounts/functionRequestAccount.ts b/javascript/solana.js/src/accounts/functionRequestAccount.ts index a862e295a..afc74d677 100644 --- a/javascript/solana.js/src/accounts/functionRequestAccount.ts +++ b/javascript/solana.js/src/accounts/functionRequestAccount.ts @@ -1,4 +1,3 @@ -import { Idl, Program } from "@coral-xyz/anchor"; import { Account } from "../accounts/account.js"; import * as errors from "../errors.js"; import * as types from "../generated/attestation-program/index.js"; @@ -10,14 +9,15 @@ import type { import { TransactionObject } from "../TransactionObject.js"; import { parseRawBuffer } from "../utils.js"; -import { FunctionAccount } from "./index.js"; +import type { SwitchboardWalletFundParams } from "./index.js"; +import { FunctionAccount, SwitchboardWallet } from "./index.js"; +import * as spl from "@solana/spl-token"; import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, } from "@solana/spl-token"; import type { - AccountMeta, Commitment, PublicKey, TransactionInstruction, @@ -44,12 +44,6 @@ export interface FunctionRequestAccountInitParams { keypair?: Keypair; authority?: PublicKey; - - /** - * An optional keypair to be used to sign the transaction if the function requires - * authorization on request initialization. - */ - functionAuthority?: Keypair; } /** @@ -88,6 +82,12 @@ export interface FunctionRequestVerifyParams { receiver: PublicKey; } +export interface FunctionRequestFundParams { + funderTokenWallet?: PublicKey; // defaults to payer tokenWallet + funderAuthority?: Keypair; // defaults to payer + transferAmount: number; +} + /** * Account type representing a Switchboard Function. * @@ -96,12 +96,6 @@ export interface FunctionRequestVerifyParams { export class FunctionRequestAccount extends Account { static accountName = "FunctionRequestAccountData"; - /** - * Get the size of an {@linkcode FunctionRequestAccount} on-chain. - */ - public readonly size = - this.program.attestationAccount.functionAccountData.size; - /** * Retrieve and decode the {@linkcode types.FunctionRequestAccountData} stored in this account. */ @@ -129,6 +123,9 @@ export class FunctionRequestAccount extends Account { + // TODO: Calculate the max size of data we can support up front then split into multiple txns + + // TODO: Add way to make this a PDA const requestKeypair = params.keypair ?? Keypair.generate(); await program.verifyNewKeypair(requestKeypair); @@ -152,9 +149,7 @@ export class FunctionRequestAccount extends Account - accountMeta.pubkey.equals(program.programId) - ? { - pubkey: accountMeta.pubkey, - isSigner: false, - isWritable: accountMeta.isWritable, - } - : accountMeta - ); - return [ new FunctionRequestAccount(program, requestKeypair.publicKey), - new TransactionObject( - payer, - [instruction], - params.functionAuthority - ? [requestKeypair, params.functionAuthority] - : [requestKeypair], - options - ), + new TransactionObject(payer, [instruction], [requestKeypair], options), ]; } @@ -206,7 +182,7 @@ export class FunctionRequestAccount extends Account this.program.signAndSend(txn, options)); } + public async fundInstruction( + payer: PublicKey, + params: FunctionRequestFundParams, + options?: TransactionObjectOptions + ): Promise { + const wrapTxn = ( + await this.program.mint.getOrCreateWrappedUserInstructions(payer, { + fundUpTo: params.transferAmount, + }) + )[1]; + + const funderAuthority = params.funderAuthority?.publicKey ?? payer; + const source = + params.funderTokenWallet ?? + this.program.mint.getAssociatedAddress(funderAuthority); + const destination = this.tokenAccount; + + const transferAmount = this.program.mint.toTokenAmount( + params.transferAmount + ); + + const signers = params.funderAuthority ? [params.funderAuthority] : []; + const ixn = spl.createTransferInstruction( + source, + destination, + funderAuthority, + transferAmount, + signers + ); + const transferTxn = new TransactionObject(payer, [ixn], signers, options); + + return wrapTxn?.combine(transferTxn) ?? transferTxn; + } + + public async fund( + params: FunctionRequestFundParams, + options?: SendTransactionObjectOptions + ): Promise { + return await this.fundInstruction( + this.program.walletPubkey, + params, + options + ).then((txn) => this.program.signAndSend(txn, options)); + } + public async triggerInstruction( payer: PublicKey, params?: FunctionRequestTriggerParams, @@ -337,7 +358,7 @@ export class FunctionRequestAccount extends Account { + static accountName = "FunctionRoutineAccountData"; + + private switchboardWallet?: SwitchboardWallet | undefined = undefined; + + /** + * Retrieve and decode the {@linkcode types.FunctionRoutineAccountData} stored in this account. + */ + public async loadData(): Promise { + const data = await types.FunctionRoutineAccountData.fetch( + this.program, + this.publicKey + ); + if (!data) { + throw new errors.AccountNotFoundError("Routine", this.publicKey); + } + + // cache this so we dont need to always re-fetch + this.switchboardWallet = new SwitchboardWallet( + this.program, + data.escrowWallet + ); + + return data; + } + + private async getSwitchboardWallet(): Promise { + if (this.switchboardWallet) { + return this.switchboardWallet; + } + + const data = await this.loadData(); + if (this.switchboardWallet) { + return this.switchboardWallet; + } + + return new SwitchboardWallet(this.program, data.escrowWallet); + } + + public static async load( + program: SwitchboardProgram, + address: PublicKey | string + ): Promise<[FunctionRoutineAccount, types.FunctionRoutineAccountData]> { + const functionAccount = new FunctionRoutineAccount(program, address); + const state = await functionAccount.loadData(); + return [functionAccount, state]; + } + + public static async createInstruction( + program: SwitchboardProgram, + payer: PublicKey, + params: FunctionRoutineAccountInitParams, + wallet?: SwitchboardWallet, + options?: TransactionObjectOptions + ): Promise<[FunctionRoutineAccount, TransactionObject]> { + // TODO: Calculate the max size of data we can support up front then split into multiple txns + + const authorityPubkey = params.authority ?? payer; + + const routineKeypair = params.keypair ?? Keypair.generate(); + await program.verifyNewKeypair(routineKeypair); + + const functionState = await params.functionAccount.loadData(); + + const cronSchedule: Buffer = params.schedule + ? Buffer.from(parseCronSchedule(params.schedule), "utf-8") + : Buffer.from(Array(64).fill(0)); + + let escrowWallet: SwitchboardWallet; + let escrowWalletAuthority: PublicKey; + if (wallet) { + escrowWallet = wallet; + escrowWalletAuthority = (await escrowWallet.loadData()).authority; + if ( + !escrowWalletAuthority.equals(payer) && + !escrowWalletAuthority.equals(authorityPubkey) + ) { + throw new errors.IncorrectAuthority( + escrowWalletAuthority, + authorityPubkey + ); + } + } else { + escrowWallet = SwitchboardWallet.fromSeed( + program, + functionState.attestationQueue, + authorityPubkey, + params.functionAccount.publicKey.toBytes() + ); + escrowWalletAuthority = authorityPubkey; + } + + const instruction = types.functionRoutineInit( + program, + { + params: { + // Metadata Config + name: new Uint8Array(Buffer.from(params.name ?? "", "utf8")), + metadata: new Uint8Array(Buffer.from(params.metadata ?? "", "utf8")), + + // Fees + bounty: params?.bounty + ? typeof params.bounty === "number" + ? new BN(params.bounty) + : params.bounty + : null, + + // Execution Config + schedule: cronSchedule, + maxContainerParamsLen: null, + containerParams: new Uint8Array( + params.containerParams ?? Buffer.from("") + ), + }, + }, + { + routine: routineKeypair.publicKey, + authority: authorityPubkey, + function: params.functionAccount.publicKey, + functionAuthority: functionState.authority, + escrowWallet: escrowWallet.publicKey, + escrowWalletAuthority: escrowWalletAuthority, + escrowTokenWallet: anchor.utils.token.associatedAddress({ + mint: program.mint.address, + owner: escrowWallet.publicKey, + }), + mint: program.mint.address, + attestationQueue: functionState.attestationQueue, + payer, + systemProgram: SystemProgram.programId, + tokenProgram: TOKEN_PROGRAM_ID, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + } + ); + return [ + new FunctionRoutineAccount(program, routineKeypair.publicKey), + new TransactionObject(payer, [instruction], [routineKeypair], options), + ]; + } + + public static async create( + program: SwitchboardProgram, + params: FunctionRoutineAccountInitParams, + wallet?: SwitchboardWallet, + options?: SendTransactionObjectOptions + ): Promise<[FunctionRoutineAccount, TransactionSignature]> { + const [account, txnObject] = await this.createInstruction( + program, + program.walletPubkey, + params, + wallet, + options + ); + const txSignature = await program.signAndSend(txnObject, options); + return [account, txSignature]; + } + + // public get wallet(): SwitchboardWallet { + // return new SwitchboardWallet(this.program, this.getEscrow()); + // } + + // public getEscrow(): PublicKey { + // return this.program.mint.getAssociatedAddress(this.publicKey); + // } + + public async getBalance(): Promise { + const switchboardWallet = await this.getSwitchboardWallet(); + return switchboardWallet.getBalance(); + } + + public async getBalanceBN(): Promise { + const switchboardWallet = await this.getSwitchboardWallet(); + return switchboardWallet.getBalanceBN(); + } + + public async setConfigInstruction( + payer: PublicKey, + params: FunctionRoutineSetConfigParams, + options?: TransactionObjectOptions + ): Promise { + const routineState = await this.loadData(); + + let name: any = null; + if (params.name !== undefined) { + name = new Uint8Array(Buffer.from(params.name ?? "", "utf8")); + } + let metadata: any = null; + if (params.metadata !== undefined) { + metadata = new Uint8Array(Buffer.from(params.metadata ?? "", "utf8")); + } + let containerParams: any = null; + if (params.containerParams !== undefined) { + containerParams = new Uint8Array( + Buffer.from(params.containerParams ?? "", "utf8") + ); + } + const setConfigIxn = types.functionRoutineSetConfig( + this.program, + { + params: { + name, + metadata, + + // Fees + bounty: params?.bounty + ? typeof params.bounty === "number" + ? new BN(params.bounty) + : params.bounty + : null, + + schedule: params?.schedule + ? Buffer.from(parseCronSchedule(params.schedule), "utf-8") + : null, + + containerParams, + appendContainerParams: params.appendContainerParams ?? false, + }, + }, + { + routine: this.publicKey, + authority: routineState.authority, + } + ); + + return new TransactionObject( + payer, + [setConfigIxn], + params?.authority ? [params.authority] : [], + options + ); + } + + public async setConfig( + params: FunctionRoutineSetConfigParams, + options?: SendTransactionObjectOptions + ): Promise { + return await this.setConfigInstruction( + this.program.walletPubkey, + params, + options + ).then((txn) => this.program.signAndSend(txn, options)); + } + + public async fundInstruction( + payer: PublicKey, + params: SwitchboardWalletFundParams, + options?: TransactionObjectOptions + ): Promise { + const switchboardWallet = await this.getSwitchboardWallet(); + return await switchboardWallet.fundInstruction(payer, params, options); + } + + public async fund( + params: SwitchboardWalletFundParams, + options?: SendTransactionObjectOptions + ): Promise { + return await this.fundInstruction( + this.program.walletPubkey, + params, + options + ).then((txn) => this.program.signAndSend(txn, options)); + } + + public verifyIxn( + params: FunctionRoutineVerifyParams + ): TransactionInstruction { + const ixn = types.functionRoutineVerify( + this.program, + { + params: { + observedTime: new BN( + params.observedTime + ? params.observedTime + : Math.floor(Date.now() / 1000) + ), + nextAllowedTimestamp: new BN(params.nextAllowedTimestamp), + errorCode: params.isFailure ? 1 : 0, + mrEnclave: Array.from(parseRawMrEnclave(params.mrEnclave)), + + containerParamsHash: Array.from( + parseRawBuffer(params.containerParamsHash) + ), + }, + }, + { + routine: this.publicKey, + functionEnclaveSigner: params.functionEnclaveSigner, + escrowWallet: params.escrowWallet, + escrowTokenWallet: anchor.utils.token.associatedAddress({ + mint: NativeMint.address, + owner: params.escrowWallet, + }), + function: params.function, + functionEscrowTokenWallet: params.functionEscrow, + verifierQuote: params.verifierQuote, + verifierEnclaveSigner: params.verifierEnclaveSigner, + verifierPermission: params.verifierPermission, + attestationQueue: params.attestationQueue, + receiver: params.receiver, + tokenProgram: TOKEN_PROGRAM_ID, + } + ); + + return ixn; + } +} diff --git a/javascript/solana.js/src/accounts/index.ts b/javascript/solana.js/src/accounts/index.ts index f0041bcd6..3229c56f8 100644 --- a/javascript/solana.js/src/accounts/index.ts +++ b/javascript/solana.js/src/accounts/index.ts @@ -9,6 +9,7 @@ export * from "./crankAccount.js"; export * from "./crankDataBuffer.js"; export * from "./functionAccount.js"; export * from "./functionRequestAccount.js"; +export * from "./functionRoutineAccount.js"; export * from "./jobAccount.js"; export * from "./leaseAccount.js"; export * from "./oracleAccount.js"; diff --git a/javascript/solana.js/src/accounts/jobAccount.ts b/javascript/solana.js/src/accounts/jobAccount.ts index 859075db6..93eeb73f4 100644 --- a/javascript/solana.js/src/accounts/jobAccount.ts +++ b/javascript/solana.js/src/accounts/jobAccount.ts @@ -41,10 +41,6 @@ export class JobAccount extends Account { */ public static getMetadata = (job: types.JobAccountData) => toUtf8(job.metadata); - /** - * Get the size of an {@linkcode JobAccount} on-chain. - */ - public size = this.program.account.jobAccountData.size; public static getAccountSize(byteLength: number): number { return 181 + byteLength; @@ -268,14 +264,7 @@ export class JobAccount extends Account { } decode(data: Buffer): types.JobAccountData { - try { - return types.JobAccountData.decode(data); - } catch { - return this.program.coder.decode( - JobAccount.accountName, - data - ); - } + return types.JobAccountData.decode(data); } static decode( @@ -285,7 +274,8 @@ export class JobAccount extends Account { if (!accountInfo || accountInfo.data === null) { throw new Error("Cannot decode empty JobAccountData"); } - return program.coder.decode(JobAccount.accountName, accountInfo?.data); + + return types.JobAccountData.decode(accountInfo.data); } static decodeJob( diff --git a/javascript/solana.js/src/accounts/leaseAccount.ts b/javascript/solana.js/src/accounts/leaseAccount.ts index aa3e5f2e2..3041925dd 100644 --- a/javascript/solana.js/src/accounts/leaseAccount.ts +++ b/javascript/solana.js/src/accounts/leaseAccount.ts @@ -37,51 +37,6 @@ export class LeaseAccount extends Account { public static size = 453; - /** - * Get the size of an {@linkcode LeaseAccount} on-chain. - */ - public size = this.program.account.leaseAccountData.size; - - /** - * Return a lease account state initialized to the default values. - */ - public static default(): types.LeaseAccountData { - const buffer = Buffer.alloc(LeaseAccount.size, 0); - types.LeaseAccountData.discriminator.copy(buffer, 0); - return types.LeaseAccountData.decode(buffer); - } - - /** - * Create a mock account info for a given lease config. Useful for test integrations. - */ - public static createMock( - programId: PublicKey, - data: Partial, - options?: { - lamports?: number; - rentEpoch?: number; - } - ): AccountInfo { - const fields: types.LeaseAccountDataFields = { - ...LeaseAccount.default(), - ...data, - // any cleanup actions here - }; - const state = new types.LeaseAccountData(fields); - - const buffer = Buffer.alloc(LeaseAccount.size, 0); - types.LeaseAccountData.discriminator.copy(buffer, 0); - types.LeaseAccountData.layout.encode(state, buffer, 8); - - return { - executable: false, - owner: programId, - lamports: options?.lamports ?? 1 * LAMPORTS_PER_SOL, - data: buffer, - rentEpoch: options?.rentEpoch ?? 0, - }; - } - /** Load an existing LeaseAccount with its current on-chain state */ public static async load( program: SwitchboardProgram, @@ -111,7 +66,7 @@ export class LeaseAccount extends Account { ): [LeaseAccount, number] { const [publicKey, bump] = PublicKey.findProgramAddressSync( [Buffer.from("LeaseAccountData"), queue.toBytes(), aggregator.toBytes()], - program.programId + program.oracleProgramId ); return [new LeaseAccount(program, publicKey), bump]; } diff --git a/javascript/solana.js/src/accounts/oracleAccount.ts b/javascript/solana.js/src/accounts/oracleAccount.ts index 7038cb9f8..9c99c98ba 100644 --- a/javascript/solana.js/src/accounts/oracleAccount.ts +++ b/javascript/solana.js/src/accounts/oracleAccount.ts @@ -40,11 +40,6 @@ export class OracleAccount extends Account { public static size = 636; - /** - * Get the size of an {@linkcode OracleAccount} on-chain. - */ - public size = this.program.account.oracleAccountData.size; - /** * Return an oracle account state initialized to the default values. */ @@ -99,14 +94,7 @@ export class OracleAccount extends Account { } decode(data: Buffer): types.OracleAccountData { - try { - return types.OracleAccountData.decode(data); - } catch { - return this.program.coder.decode( - OracleAccount.accountName, - data - ); - } + return types.OracleAccountData.decode(data); } /** @@ -171,7 +159,7 @@ export class OracleAccount extends Account { ): [OracleAccount, number] { const [publicKey, bump] = PublicKey.findProgramAddressSync( [Buffer.from("OracleAccountData"), queue.toBuffer(), wallet.toBuffer()], - program.programId + program.oracleProgramId ); return [new OracleAccount(program, publicKey), bump]; } diff --git a/javascript/solana.js/src/accounts/permissionAccount.ts b/javascript/solana.js/src/accounts/permissionAccount.ts index bfa0533db..54f3fcd2e 100644 --- a/javascript/solana.js/src/accounts/permissionAccount.ts +++ b/javascript/solana.js/src/accounts/permissionAccount.ts @@ -51,11 +51,6 @@ export class PermissionAccount extends Account { public static size = 372; - /** - * Returns the size of an on-chain {@linkcode PermissionAccount}. - */ - public readonly size = this.program.account.permissionAccountData.size; - /** * Retrieve and decode the {@linkcode types.PermissionAccountData} stored in this account. */ @@ -166,7 +161,7 @@ export class PermissionAccount extends Account { granter.toBytes(), grantee.toBytes(), ], - program.programId + program.oracleProgramId ); return [new PermissionAccount(program, publicKey), bump]; } diff --git a/javascript/solana.js/src/accounts/programStateAccount.ts b/javascript/solana.js/src/accounts/programStateAccount.ts index 6b2bba767..8401df86b 100644 --- a/javascript/solana.js/src/accounts/programStateAccount.ts +++ b/javascript/solana.js/src/accounts/programStateAccount.ts @@ -25,11 +25,6 @@ export class ProgramStateAccount extends Account { public static size = 1128; - /** - * @return account size of the global {@linkcode ProgramStateAccount}. - */ - public readonly size = this.program.account.sbState.size; - /** * Finds the {@linkcode ProgramStateAccount} from the static seed from which it was generated. * @return ProgramStateAccount and PDA bump tuple. @@ -39,7 +34,7 @@ export class ProgramStateAccount extends Account { ): [ProgramStateAccount, number] { const [publicKey, bump] = PublicKey.findProgramAddressSync( [Buffer.from("STATE")], - program.programId + program.oracleProgramId ); return [new ProgramStateAccount(program, publicKey), bump]; } diff --git a/javascript/solana.js/src/accounts/queueAccount.ts b/javascript/solana.js/src/accounts/queueAccount.ts index 760241002..2abe0b5fb 100644 --- a/javascript/solana.js/src/accounts/queueAccount.ts +++ b/javascript/solana.js/src/accounts/queueAccount.ts @@ -59,11 +59,6 @@ export class QueueAccount extends Account { public static size = 1269; - /** - * Get the size of an {@linkcode QueueAccount} on-chain. - */ - public readonly size = this.program.account.oracleQueueAccountData.size; - /** * Returns the queue's name buffer in a stringified format. */ @@ -124,7 +119,7 @@ export class QueueAccount extends Account { /** * Get the spl Mint associated with this {@linkcode QueueAccount}. */ - public get mint(): spl.Mint { + public get mint(): { address: PublicKey; decimals: number } { return this.program.mint.mint; } @@ -191,7 +186,7 @@ export class QueueAccount extends Account { lamports: await program.connection.getMinimumBalanceForRentExemption( queueDataSize ), - programId: program.programId, + programId: program.oracleProgramId, }), types.oracleQueueInit( program, diff --git a/javascript/solana.js/src/accounts/switchboardWallet.ts b/javascript/solana.js/src/accounts/switchboardWallet.ts index 810042226..1b4a58905 100644 --- a/javascript/solana.js/src/accounts/switchboardWallet.ts +++ b/javascript/solana.js/src/accounts/switchboardWallet.ts @@ -67,20 +67,8 @@ export type SwitchboardWalletWithEscrow = SwitchboardWalletState & { export class SwitchboardWallet extends Account { static accountName = "SwitchboardWallet"; - private _tokenWallet: PublicKey | undefined = undefined; - - /** - * Returns the size of an on-chain {@linkcode SwitchboardWallet}. - */ - public readonly size = this.program.attestationAccount.switchboardWallet.size; - public get tokenWallet(): PublicKey { - if (!this._tokenWallet) { - this._tokenWallet = this.program.mint.getAssociatedAddress( - this.publicKey - ); - } - return this._tokenWallet; + return this.program.mint.getAssociatedAddress(this.publicKey); } public static parseName(name: string | PublicKey | Uint8Array): Uint8Array { @@ -130,7 +118,7 @@ export class SwitchboardWallet extends Account { const tokenAccountInfo = accountInfos.shift(); if (!tokenAccountInfo) { throw new errors.AccountNotFoundError( - "SwitchboardWallet tokenWallet", + "SwitchboardWallet tokenAccount", this.tokenWallet ); } @@ -221,7 +209,7 @@ export class SwitchboardWallet extends Account { const walletInitIxn = types.walletInit( program, - { params: { name: Buffer.from(nameSeed), maxLen: maxLen ?? null } }, + { params: { name: Buffer.from(nameSeed) } }, { wallet: switchboardWallet.publicKey, mint: program.mint.address, @@ -229,7 +217,6 @@ export class SwitchboardWallet extends Account { attestationQueue: attestationQueue, tokenWallet: switchboardWallet.tokenWallet, payer: payer, - state: program.attestationProgramState.publicKey, tokenProgram: spl.TOKEN_PROGRAM_ID, associatedTokenProgram: spl.ASSOCIATED_TOKEN_PROGRAM_ID, systemProgram: SystemProgram.programId, diff --git a/javascript/solana.js/src/accounts/verifierAccount.ts b/javascript/solana.js/src/accounts/verifierAccount.ts index 689003c44..fb55e2782 100644 --- a/javascript/solana.js/src/accounts/verifierAccount.ts +++ b/javascript/solana.js/src/accounts/verifierAccount.ts @@ -224,12 +224,6 @@ export class VerifierAccount extends Account { ); } - /** - * Get the size of an {@linkcode VerifierAccount} on-chain. - */ - public readonly size = - this.program.attestationAccount.verifierAccountData.size; - /** * Retrieve and decode the {@linkcode types.VerifierAccountData} stored in this account. */ diff --git a/javascript/solana.js/src/accounts/vrfAccount.ts b/javascript/solana.js/src/accounts/vrfAccount.ts index 63edcdbf0..50250a78d 100644 --- a/javascript/solana.js/src/accounts/vrfAccount.ts +++ b/javascript/solana.js/src/accounts/vrfAccount.ts @@ -40,11 +40,6 @@ import { BN, promiseWithTimeout } from "@switchboard-xyz/common"; export class VrfAccount extends Account { static accountName = "VrfAccountData"; - /** - * Returns the size of an on-chain {@linkcode VrfAccount}. - */ - public readonly size = this.program.account.vrfAccountData.size; - /** * Return a vrf account state initialized to the default values. */ @@ -108,7 +103,7 @@ export class VrfAccount extends Account { ): Promise<[VrfAccount, TransactionObject]> { await program.verifyNewKeypair(params.vrfKeypair); const vrfAccount = new VrfAccount(program, params.vrfKeypair.publicKey); - const size = program.account.vrfAccountData.size; + const size = (await program.oracleProgram).account.vrfAccountData.size; const escrow = program.mint.getAssociatedAddress(vrfAccount.publicKey); @@ -132,7 +127,7 @@ export class VrfAccount extends Account { lamports: await program.connection.getMinimumBalanceForRentExemption( size ), - programId: program.programId, + programId: program.oracleProgramId, }), types.vrfInit( program, diff --git a/javascript/solana.js/src/accounts/vrfLiteAccount.ts b/javascript/solana.js/src/accounts/vrfLiteAccount.ts index 97a73c75d..038b9e6e3 100644 --- a/javascript/solana.js/src/accounts/vrfLiteAccount.ts +++ b/javascript/solana.js/src/accounts/vrfLiteAccount.ts @@ -62,8 +62,6 @@ export interface VrfLiteCloseParams { } export class VrfLiteAccount extends Account { - public size = this.program.account.vrfLiteAccountData.size; - /** * Invoke a callback each time a VrfAccount's data has changed on-chain. * @param callback - the callback invoked when the vrf state changes diff --git a/javascript/solana.js/src/accounts/vrfPoolAccount.ts b/javascript/solana.js/src/accounts/vrfPoolAccount.ts index a68406fe8..77636da77 100644 --- a/javascript/solana.js/src/accounts/vrfPoolAccount.ts +++ b/javascript/solana.js/src/accounts/vrfPoolAccount.ts @@ -78,8 +78,6 @@ export type VrfPoolAccountData = types.VrfPoolAccountData & { }; export class VrfPoolAccount extends Account { - public size = this.program.account.vrfPoolAccountData.size; - /** * Invoke a callback each time a VrfAccount's data has changed on-chain. * @param callback - the callback invoked when the vrf state changes @@ -131,7 +129,7 @@ export class VrfPoolAccount extends Account { if (info === null) { throw new AccountNotFoundError("VrfPool", this.publicKey); } - if (!info.owner.equals(this.program.programId)) { + if (!info.owner.equals(this.program.oracleProgramId)) { throw new Error("account doesn't belong to this program"); } @@ -169,7 +167,7 @@ export class VrfPoolAccount extends Account { space ), space: space, - programId: program.programId, + programId: program.oracleProgramId, }), types.vrfPoolInit( program, @@ -637,8 +635,8 @@ export class VrfPoolAccount extends Account { const eventPromise: Promise = promiseWithTimeout( timeout, - new Promise((resolve: (result: VrfPoolRequestEvent) => void) => { - ws = this.program.addEventListener( + new Promise(async (resolve: (result: VrfPoolRequestEvent) => void) => { + ws = await this.program.addEventListener( "VrfPoolRequestEvent", (event, slot, signature) => { if (event.vrfPoolPubkey.equals(this.publicKey)) { diff --git a/javascript/solana.js/src/generated/attestation-program/accounts/AttestationQueueAccountData.ts b/javascript/solana.js/src/generated/attestation-program/accounts/AttestationQueueAccountData.ts index 963c22986..f3f89970e 100644 --- a/javascript/solana.js/src/generated/attestation-program/accounts/AttestationQueueAccountData.ts +++ b/javascript/solana.js/src/generated/attestation-program/accounts/AttestationQueueAccountData.ts @@ -89,6 +89,16 @@ export interface AttestationQueueAccountDataJSON { ebuf: Array; } +/** + * An AttestationQueue represents a round-robin queue of verifier oracles who attest on-chain + * whether a Switchboard Function was executed within an enclave against an expected set of + * enclave measurements. + * + * For an oracle to join the queue, the oracle must first submit their enclave quote on-chain and + * wait for an existing verifier to attest their quote. If the oracle's quote matches an expected + * measurement within the queues mr_enclaves config, it is granted permissions and will start + * being assigned update requests. + */ export class AttestationQueueAccountData { /** The address of the authority which is permitted to add/remove allowed enclave measurements. */ readonly authority: PublicKey; diff --git a/javascript/solana.js/src/generated/attestation-program/accounts/FunctionAccountData.ts b/javascript/solana.js/src/generated/attestation-program/accounts/FunctionAccountData.ts index b52bfb6fc..5dc02e635 100644 --- a/javascript/solana.js/src/generated/attestation-program/accounts/FunctionAccountData.ts +++ b/javascript/solana.js/src/generated/attestation-program/accounts/FunctionAccountData.ts @@ -64,17 +64,21 @@ export interface FunctionAccountDataFields { /** Number of requests created for this function. Used to prevent closing when there are live requests. */ numRequests: BN; /** Whether custom requests have been disabled for this function. */ - requestsDisabled: boolean; + requestsDisabled: number; /** * Whether new requests need to be authorized by the FunctionAccount authority before being initialized. * Useful if you want to use CPIs to control request account creation. */ - requestsRequireAuthorization: boolean; + requestsRequireAuthorization: number; /** DEPRECATED. */ reserved1: Array; - /** The lamports paid to the FunctionAccount escrow on each successful update request. */ - requestsFee: BN; - /** The SwitchboardWallet that will handle pre-funding rewards paid out to function runners. */ + /** + * The dev fee that is paid out from the request's escrow to the function's escrow on each successful invocation. + * This is used to reward the function maintainer for providing the function. + * 0 = No Fee. Sender = requests's escrow_token_wallet. Receiver = function's reward_token_wallet. + */ + requestsDevFee: BN; + /** The SwitchboardWallet that will handle pre-funding rewards paid out to function verifiers. */ escrowWallet: PublicKey; /** The escrow_wallet TokenAccount that handles pre-funding rewards paid out to function runners. */ escrowTokenWallet: PublicKey; @@ -85,6 +89,31 @@ export interface FunctionAccountDataFields { rewardEscrowWallet: PublicKey; /** The reward_escrow_wallet TokenAccount used to acrue rewards from requests made with custom parameters. */ rewardEscrowTokenWallet: PublicKey; + /** The last reported error code if the most recent response was a failure */ + errorStatus: number; + /** Number of routines created for this function. Used to prevent closing when there are live routines. */ + numRoutines: BN; + /** Whether custom routines have been disabled for this function. */ + routinesDisabled: types.BoolWithLockKind; + /** + * Whether new routines need to be authorized by the FunctionAccount authority before being initialized. + * Useful if you want to provide AccessControl and only allow certain parties to run routines. + */ + routinesRequireAuthorization: number; + /** + * The fee that is paid out from the routine's escrow to the function's escrow on each successful invocation. + * This is used to reward the function maintainer for providing the function. + * 0 = No Fee. Sender = routine's escrow_token_wallet. Receiver = function's reward_token_wallet. + */ + routinesDevFee: BN; + /** The functions MRENCLAVE measurement dictating the contents of the secure enclave. */ + mrEnclave: Array; + /** The VerificationStatus of the quote. */ + verificationStatus: number; + /** The unix timestamp when the quote was last verified. */ + verificationTimestamp: BN; + /** The unix timestamp when the quotes verification status expires. */ + validUntil: BN; /** Reserved. */ ebuf: Array; } @@ -148,17 +177,21 @@ export interface FunctionAccountDataJSON { /** Number of requests created for this function. Used to prevent closing when there are live requests. */ numRequests: string; /** Whether custom requests have been disabled for this function. */ - requestsDisabled: boolean; + requestsDisabled: number; /** * Whether new requests need to be authorized by the FunctionAccount authority before being initialized. * Useful if you want to use CPIs to control request account creation. */ - requestsRequireAuthorization: boolean; + requestsRequireAuthorization: number; /** DEPRECATED. */ reserved1: Array; - /** The lamports paid to the FunctionAccount escrow on each successful update request. */ - requestsFee: string; - /** The SwitchboardWallet that will handle pre-funding rewards paid out to function runners. */ + /** + * The dev fee that is paid out from the request's escrow to the function's escrow on each successful invocation. + * This is used to reward the function maintainer for providing the function. + * 0 = No Fee. Sender = requests's escrow_token_wallet. Receiver = function's reward_token_wallet. + */ + requestsDevFee: string; + /** The SwitchboardWallet that will handle pre-funding rewards paid out to function verifiers. */ escrowWallet: string; /** The escrow_wallet TokenAccount that handles pre-funding rewards paid out to function runners. */ escrowTokenWallet: string; @@ -169,6 +202,31 @@ export interface FunctionAccountDataJSON { rewardEscrowWallet: string; /** The reward_escrow_wallet TokenAccount used to acrue rewards from requests made with custom parameters. */ rewardEscrowTokenWallet: string; + /** The last reported error code if the most recent response was a failure */ + errorStatus: number; + /** Number of routines created for this function. Used to prevent closing when there are live routines. */ + numRoutines: string; + /** Whether custom routines have been disabled for this function. */ + routinesDisabled: types.BoolWithLockJSON; + /** + * Whether new routines need to be authorized by the FunctionAccount authority before being initialized. + * Useful if you want to provide AccessControl and only allow certain parties to run routines. + */ + routinesRequireAuthorization: number; + /** + * The fee that is paid out from the routine's escrow to the function's escrow on each successful invocation. + * This is used to reward the function maintainer for providing the function. + * 0 = No Fee. Sender = routine's escrow_token_wallet. Receiver = function's reward_token_wallet. + */ + routinesDevFee: string; + /** The functions MRENCLAVE measurement dictating the contents of the secure enclave. */ + mrEnclave: Array; + /** The VerificationStatus of the quote. */ + verificationStatus: number; + /** The unix timestamp when the quote was last verified. */ + verificationTimestamp: string; + /** The unix timestamp when the quotes verification status expires. */ + validUntil: string; /** Reserved. */ ebuf: Array; } @@ -232,17 +290,21 @@ export class FunctionAccountData { /** Number of requests created for this function. Used to prevent closing when there are live requests. */ readonly numRequests: BN; /** Whether custom requests have been disabled for this function. */ - readonly requestsDisabled: boolean; + readonly requestsDisabled: number; /** * Whether new requests need to be authorized by the FunctionAccount authority before being initialized. * Useful if you want to use CPIs to control request account creation. */ - readonly requestsRequireAuthorization: boolean; + readonly requestsRequireAuthorization: number; /** DEPRECATED. */ readonly reserved1: Array; - /** The lamports paid to the FunctionAccount escrow on each successful update request. */ - readonly requestsFee: BN; - /** The SwitchboardWallet that will handle pre-funding rewards paid out to function runners. */ + /** + * The dev fee that is paid out from the request's escrow to the function's escrow on each successful invocation. + * This is used to reward the function maintainer for providing the function. + * 0 = No Fee. Sender = requests's escrow_token_wallet. Receiver = function's reward_token_wallet. + */ + readonly requestsDevFee: BN; + /** The SwitchboardWallet that will handle pre-funding rewards paid out to function verifiers. */ readonly escrowWallet: PublicKey; /** The escrow_wallet TokenAccount that handles pre-funding rewards paid out to function runners. */ readonly escrowTokenWallet: PublicKey; @@ -253,6 +315,31 @@ export class FunctionAccountData { readonly rewardEscrowWallet: PublicKey; /** The reward_escrow_wallet TokenAccount used to acrue rewards from requests made with custom parameters. */ readonly rewardEscrowTokenWallet: PublicKey; + /** The last reported error code if the most recent response was a failure */ + readonly errorStatus: number; + /** Number of routines created for this function. Used to prevent closing when there are live routines. */ + readonly numRoutines: BN; + /** Whether custom routines have been disabled for this function. */ + readonly routinesDisabled: types.BoolWithLockKind; + /** + * Whether new routines need to be authorized by the FunctionAccount authority before being initialized. + * Useful if you want to provide AccessControl and only allow certain parties to run routines. + */ + readonly routinesRequireAuthorization: number; + /** + * The fee that is paid out from the routine's escrow to the function's escrow on each successful invocation. + * This is used to reward the function maintainer for providing the function. + * 0 = No Fee. Sender = routine's escrow_token_wallet. Receiver = function's reward_token_wallet. + */ + readonly routinesDevFee: BN; + /** The functions MRENCLAVE measurement dictating the contents of the secure enclave. */ + readonly mrEnclave: Array; + /** The VerificationStatus of the quote. */ + readonly verificationStatus: number; + /** The unix timestamp when the quote was last verified. */ + readonly verificationTimestamp: BN; + /** The unix timestamp when the quotes verification status expires. */ + readonly validUntil: BN; /** Reserved. */ readonly ebuf: Array; @@ -290,15 +377,24 @@ export class FunctionAccountData { borsh.i64("triggeredSince"), borsh.i64("permissionExpiration"), borsh.u64("numRequests"), - borsh.bool("requestsDisabled"), - borsh.bool("requestsRequireAuthorization"), + borsh.u8("requestsDisabled"), + borsh.u8("requestsRequireAuthorization"), borsh.array(borsh.u8(), 8, "reserved1"), - borsh.u64("requestsFee"), + borsh.u64("requestsDevFee"), borsh.publicKey("escrowWallet"), borsh.publicKey("escrowTokenWallet"), borsh.publicKey("rewardEscrowWallet"), borsh.publicKey("rewardEscrowTokenWallet"), - borsh.array(borsh.u8(), 1024, "ebuf"), + borsh.u8("errorStatus"), + borsh.u64("numRoutines"), + types.BoolWithLock.layout("routinesDisabled"), + borsh.u8("routinesRequireAuthorization"), + borsh.u64("routinesDevFee"), + borsh.array(borsh.u8(), 32, "mrEnclave"), + borsh.u8("verificationStatus"), + borsh.i64("verificationTimestamp"), + borsh.i64("validUntil"), + borsh.array(borsh.u8(), 956, "ebuf"), ]); constructor(fields: FunctionAccountDataFields) { @@ -334,11 +430,20 @@ export class FunctionAccountData { this.requestsDisabled = fields.requestsDisabled; this.requestsRequireAuthorization = fields.requestsRequireAuthorization; this.reserved1 = fields.reserved1; - this.requestsFee = fields.requestsFee; + this.requestsDevFee = fields.requestsDevFee; this.escrowWallet = fields.escrowWallet; this.escrowTokenWallet = fields.escrowTokenWallet; this.rewardEscrowWallet = fields.rewardEscrowWallet; this.rewardEscrowTokenWallet = fields.rewardEscrowTokenWallet; + this.errorStatus = fields.errorStatus; + this.numRoutines = fields.numRoutines; + this.routinesDisabled = fields.routinesDisabled; + this.routinesRequireAuthorization = fields.routinesRequireAuthorization; + this.routinesDevFee = fields.routinesDevFee; + this.mrEnclave = fields.mrEnclave; + this.verificationStatus = fields.verificationStatus; + this.verificationTimestamp = fields.verificationTimestamp; + this.validUntil = fields.validUntil; this.ebuf = fields.ebuf; } @@ -418,11 +523,20 @@ export class FunctionAccountData { requestsDisabled: dec.requestsDisabled, requestsRequireAuthorization: dec.requestsRequireAuthorization, reserved1: dec.reserved1, - requestsFee: dec.requestsFee, + requestsDevFee: dec.requestsDevFee, escrowWallet: dec.escrowWallet, escrowTokenWallet: dec.escrowTokenWallet, rewardEscrowWallet: dec.rewardEscrowWallet, rewardEscrowTokenWallet: dec.rewardEscrowTokenWallet, + errorStatus: dec.errorStatus, + numRoutines: dec.numRoutines, + routinesDisabled: types.BoolWithLock.fromDecoded(dec.routinesDisabled), + routinesRequireAuthorization: dec.routinesRequireAuthorization, + routinesDevFee: dec.routinesDevFee, + mrEnclave: dec.mrEnclave, + verificationStatus: dec.verificationStatus, + verificationTimestamp: dec.verificationTimestamp, + validUntil: dec.validUntil, ebuf: dec.ebuf, }); } @@ -461,11 +575,20 @@ export class FunctionAccountData { requestsDisabled: this.requestsDisabled, requestsRequireAuthorization: this.requestsRequireAuthorization, reserved1: this.reserved1, - requestsFee: this.requestsFee.toString(), + requestsDevFee: this.requestsDevFee.toString(), escrowWallet: this.escrowWallet.toString(), escrowTokenWallet: this.escrowTokenWallet.toString(), rewardEscrowWallet: this.rewardEscrowWallet.toString(), rewardEscrowTokenWallet: this.rewardEscrowTokenWallet.toString(), + errorStatus: this.errorStatus, + numRoutines: this.numRoutines.toString(), + routinesDisabled: this.routinesDisabled.toJSON(), + routinesRequireAuthorization: this.routinesRequireAuthorization, + routinesDevFee: this.routinesDevFee.toString(), + mrEnclave: this.mrEnclave, + verificationStatus: this.verificationStatus, + verificationTimestamp: this.verificationTimestamp.toString(), + validUntil: this.validUntil.toString(), ebuf: this.ebuf, }; } @@ -504,11 +627,20 @@ export class FunctionAccountData { requestsDisabled: obj.requestsDisabled, requestsRequireAuthorization: obj.requestsRequireAuthorization, reserved1: obj.reserved1, - requestsFee: new BN(obj.requestsFee), + requestsDevFee: new BN(obj.requestsDevFee), escrowWallet: new PublicKey(obj.escrowWallet), escrowTokenWallet: new PublicKey(obj.escrowTokenWallet), rewardEscrowWallet: new PublicKey(obj.rewardEscrowWallet), rewardEscrowTokenWallet: new PublicKey(obj.rewardEscrowTokenWallet), + errorStatus: obj.errorStatus, + numRoutines: new BN(obj.numRoutines), + routinesDisabled: types.BoolWithLock.fromJSON(obj.routinesDisabled), + routinesRequireAuthorization: obj.routinesRequireAuthorization, + routinesDevFee: new BN(obj.routinesDevFee), + mrEnclave: obj.mrEnclave, + verificationStatus: obj.verificationStatus, + verificationTimestamp: new BN(obj.verificationTimestamp), + validUntil: new BN(obj.validUntil), ebuf: obj.ebuf, }); } diff --git a/javascript/solana.js/src/generated/attestation-program/accounts/FunctionRequestAccountData.ts b/javascript/solana.js/src/generated/attestation-program/accounts/FunctionRequestAccountData.ts index f9ac33799..4722ed7ef 100644 --- a/javascript/solana.js/src/generated/attestation-program/accounts/FunctionRequestAccountData.ts +++ b/javascript/solana.js/src/generated/attestation-program/accounts/FunctionRequestAccountData.ts @@ -37,6 +37,8 @@ export interface FunctionRequestAccountDataFields { createdAt: BN; /** The slot when the account can be garbage collected and closed by anyone for a portion of the rent. */ garbageCollectionSlot: BN | null; + /** The last recorded error code if most recent response was an error. */ + errorStatus: number; /** Reserved. */ ebuf: Array; } @@ -73,6 +75,8 @@ export interface FunctionRequestAccountDataJSON { createdAt: string; /** The slot when the account can be garbage collected and closed by anyone for a portion of the rent. */ garbageCollectionSlot: string | null; + /** The last recorded error code if most recent response was an error. */ + errorStatus: number; /** Reserved. */ ebuf: Array; } @@ -109,6 +113,8 @@ export class FunctionRequestAccountData { readonly createdAt: BN; /** The slot when the account can be garbage collected and closed by anyone for a portion of the rent. */ readonly garbageCollectionSlot: BN | null; + /** The last recorded error code if most recent response was an error. */ + readonly errorStatus: number; /** Reserved. */ readonly ebuf: Array; @@ -131,7 +137,8 @@ export class FunctionRequestAccountData { borsh.vecU8("containerParams"), borsh.i64("createdAt"), borsh.option(borsh.u64(), "garbageCollectionSlot"), - borsh.array(borsh.u8(), 256, "ebuf"), + borsh.u8("errorStatus"), + borsh.array(borsh.u8(), 255, "ebuf"), ]); constructor(fields: FunctionRequestAccountDataFields) { @@ -153,6 +160,7 @@ export class FunctionRequestAccountData { this.containerParams = fields.containerParams; this.createdAt = fields.createdAt; this.garbageCollectionSlot = fields.garbageCollectionSlot; + this.errorStatus = fields.errorStatus; this.ebuf = fields.ebuf; } @@ -222,6 +230,7 @@ export class FunctionRequestAccountData { ), createdAt: dec.createdAt, garbageCollectionSlot: dec.garbageCollectionSlot, + errorStatus: dec.errorStatus, ebuf: dec.ebuf, }); } @@ -244,6 +253,7 @@ export class FunctionRequestAccountData { garbageCollectionSlot: (this.garbageCollectionSlot && this.garbageCollectionSlot.toString()) || null, + errorStatus: this.errorStatus, ebuf: this.ebuf, }; } @@ -272,6 +282,7 @@ export class FunctionRequestAccountData { garbageCollectionSlot: (obj.garbageCollectionSlot && new BN(obj.garbageCollectionSlot)) || null, + errorStatus: obj.errorStatus, ebuf: obj.ebuf, }); } diff --git a/javascript/solana.js/src/generated/attestation-program/accounts/FunctionRoutineAccountData.ts b/javascript/solana.js/src/generated/attestation-program/accounts/FunctionRoutineAccountData.ts new file mode 100644 index 000000000..bf0c2721c --- /dev/null +++ b/javascript/solana.js/src/generated/attestation-program/accounts/FunctionRoutineAccountData.ts @@ -0,0 +1,395 @@ +import type { SwitchboardProgram } from "../../../SwitchboardProgram.js"; +import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars + +import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars +import { Connection, PublicKey } from "@solana/web3.js"; +import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars + +export interface FunctionRoutineAccountDataFields { + /** The name of the function routine for easier identification. */ + name: Array; + /** The metadata of the function routine for easier identification. */ + metadata: Array; + /** The unix timestamp when the function routine was created. */ + createdAt: BN; + /** The unix timestamp when the function routine config was changed. */ + updatedAt: BN; + /** Flag to disable the function and prevent new verification requests. */ + isDisabled: types.ResourceLevelKind; + /** The type of resource that disabled the routine. */ + status: types.RoutineStatusKind; + /** The last reported error code if the most recent response was a failure */ + errorStatus: number; + /** The enclave generated signer for this routine. */ + enclaveSigner: PublicKey; + /** The verifier oracle who signed this verification. */ + verifier: PublicKey; + /** The SOL bounty in lamports used to incentivize a verifier to expedite the request. 0 = no bounty. Receiver = verifier oracle. */ + bounty: BN; + /** Signer allowed to manage the routine. */ + authority: PublicKey; + /** The default destination for rent exemption when the account is closed. */ + payer: PublicKey; + /** The function that manages the mr_enclave set for this routine. */ + function: PublicKey; + /** The Attestation Queue for this request. */ + attestationQueue: PublicKey; + /** The tokenAccount escrow */ + escrowWallet: PublicKey; + /** The TokenAccount with funds for the escrow. */ + escrowTokenWallet: PublicKey; + /** + * The index of the verifier on the queue that is assigned to process the next invocation. + * This is incremented after each invocation in a round-robin fashion. + */ + queueIdx: number; + /** The cron schedule to run the function on. */ + schedule: Array; + /** The maximum number of bytes to pass to the container params. */ + maxContainerParamsLen: number; + /** + * Hash of the serialized container_params to prevent RPC tampering. + * Should be verified within your function to ensure you are using the correct parameters. + */ + containerParamsHash: Array; + /** The stringified container params to pass to the function. */ + containerParams: Uint8Array; + /** The unix timestamp when the function was last run. */ + lastExecutionTimestamp: BN; + /** The unix timestamp when the function was last run successfully. */ + lastSuccessfulExecutionTimestamp: BN; + /** The unix timestamp when the function is allowed to run next. */ + nextAllowedTimestamp: BN; + /** Reserved. */ + ebuf: Array; +} + +export interface FunctionRoutineAccountDataJSON { + /** The name of the function routine for easier identification. */ + name: Array; + /** The metadata of the function routine for easier identification. */ + metadata: Array; + /** The unix timestamp when the function routine was created. */ + createdAt: string; + /** The unix timestamp when the function routine config was changed. */ + updatedAt: string; + /** Flag to disable the function and prevent new verification requests. */ + isDisabled: types.ResourceLevelJSON; + /** The type of resource that disabled the routine. */ + status: types.RoutineStatusJSON; + /** The last reported error code if the most recent response was a failure */ + errorStatus: number; + /** The enclave generated signer for this routine. */ + enclaveSigner: string; + /** The verifier oracle who signed this verification. */ + verifier: string; + /** The SOL bounty in lamports used to incentivize a verifier to expedite the request. 0 = no bounty. Receiver = verifier oracle. */ + bounty: string; + /** Signer allowed to manage the routine. */ + authority: string; + /** The default destination for rent exemption when the account is closed. */ + payer: string; + /** The function that manages the mr_enclave set for this routine. */ + function: string; + /** The Attestation Queue for this request. */ + attestationQueue: string; + /** The tokenAccount escrow */ + escrowWallet: string; + /** The TokenAccount with funds for the escrow. */ + escrowTokenWallet: string; + /** + * The index of the verifier on the queue that is assigned to process the next invocation. + * This is incremented after each invocation in a round-robin fashion. + */ + queueIdx: number; + /** The cron schedule to run the function on. */ + schedule: Array; + /** The maximum number of bytes to pass to the container params. */ + maxContainerParamsLen: number; + /** + * Hash of the serialized container_params to prevent RPC tampering. + * Should be verified within your function to ensure you are using the correct parameters. + */ + containerParamsHash: Array; + /** The stringified container params to pass to the function. */ + containerParams: Array; + /** The unix timestamp when the function was last run. */ + lastExecutionTimestamp: string; + /** The unix timestamp when the function was last run successfully. */ + lastSuccessfulExecutionTimestamp: string; + /** The unix timestamp when the function is allowed to run next. */ + nextAllowedTimestamp: string; + /** Reserved. */ + ebuf: Array; +} + +/** + * The function routine account provides scheduled execution of Switchboard Functions + * with a configurable cron-based schedule and container parameters. + * + * Function routines maintain their own queue_idx to provide round-robin assignment of + * verifiers for each settled execution. This is incremented after each invocation. + * + * Function routines can share a SwitchboardWallet as long as the escrow authority has + * signed the transaction. + */ +export class FunctionRoutineAccountData { + /** The name of the function routine for easier identification. */ + readonly name: Array; + /** The metadata of the function routine for easier identification. */ + readonly metadata: Array; + /** The unix timestamp when the function routine was created. */ + readonly createdAt: BN; + /** The unix timestamp when the function routine config was changed. */ + readonly updatedAt: BN; + /** Flag to disable the function and prevent new verification requests. */ + readonly isDisabled: types.ResourceLevelKind; + /** The type of resource that disabled the routine. */ + readonly status: types.RoutineStatusKind; + /** The last reported error code if the most recent response was a failure */ + readonly errorStatus: number; + /** The enclave generated signer for this routine. */ + readonly enclaveSigner: PublicKey; + /** The verifier oracle who signed this verification. */ + readonly verifier: PublicKey; + /** The SOL bounty in lamports used to incentivize a verifier to expedite the request. 0 = no bounty. Receiver = verifier oracle. */ + readonly bounty: BN; + /** Signer allowed to manage the routine. */ + readonly authority: PublicKey; + /** The default destination for rent exemption when the account is closed. */ + readonly payer: PublicKey; + /** The function that manages the mr_enclave set for this routine. */ + readonly function: PublicKey; + /** The Attestation Queue for this request. */ + readonly attestationQueue: PublicKey; + /** The tokenAccount escrow */ + readonly escrowWallet: PublicKey; + /** The TokenAccount with funds for the escrow. */ + readonly escrowTokenWallet: PublicKey; + /** + * The index of the verifier on the queue that is assigned to process the next invocation. + * This is incremented after each invocation in a round-robin fashion. + */ + readonly queueIdx: number; + /** The cron schedule to run the function on. */ + readonly schedule: Array; + /** The maximum number of bytes to pass to the container params. */ + readonly maxContainerParamsLen: number; + /** + * Hash of the serialized container_params to prevent RPC tampering. + * Should be verified within your function to ensure you are using the correct parameters. + */ + readonly containerParamsHash: Array; + /** The stringified container params to pass to the function. */ + readonly containerParams: Uint8Array; + /** The unix timestamp when the function was last run. */ + readonly lastExecutionTimestamp: BN; + /** The unix timestamp when the function was last run successfully. */ + readonly lastSuccessfulExecutionTimestamp: BN; + /** The unix timestamp when the function is allowed to run next. */ + readonly nextAllowedTimestamp: BN; + /** Reserved. */ + readonly ebuf: Array; + + static readonly discriminator = Buffer.from([ + 93, 99, 13, 119, 129, 127, 168, 18, + ]); + + static readonly layout = borsh.struct([ + borsh.array(borsh.u8(), 64, "name"), + borsh.array(borsh.u8(), 256, "metadata"), + borsh.i64("createdAt"), + borsh.i64("updatedAt"), + types.ResourceLevel.layout("isDisabled"), + types.RoutineStatus.layout("status"), + borsh.u8("errorStatus"), + borsh.publicKey("enclaveSigner"), + borsh.publicKey("verifier"), + borsh.u64("bounty"), + borsh.publicKey("authority"), + borsh.publicKey("payer"), + borsh.publicKey("function"), + borsh.publicKey("attestationQueue"), + borsh.publicKey("escrowWallet"), + borsh.publicKey("escrowTokenWallet"), + borsh.u32("queueIdx"), + borsh.array(borsh.u8(), 64, "schedule"), + borsh.u32("maxContainerParamsLen"), + borsh.array(borsh.u8(), 32, "containerParamsHash"), + borsh.vecU8("containerParams"), + borsh.i64("lastExecutionTimestamp"), + borsh.i64("lastSuccessfulExecutionTimestamp"), + borsh.i64("nextAllowedTimestamp"), + borsh.array(borsh.u8(), 512, "ebuf"), + ]); + + constructor(fields: FunctionRoutineAccountDataFields) { + this.name = fields.name; + this.metadata = fields.metadata; + this.createdAt = fields.createdAt; + this.updatedAt = fields.updatedAt; + this.isDisabled = fields.isDisabled; + this.status = fields.status; + this.errorStatus = fields.errorStatus; + this.enclaveSigner = fields.enclaveSigner; + this.verifier = fields.verifier; + this.bounty = fields.bounty; + this.authority = fields.authority; + this.payer = fields.payer; + this.function = fields.function; + this.attestationQueue = fields.attestationQueue; + this.escrowWallet = fields.escrowWallet; + this.escrowTokenWallet = fields.escrowTokenWallet; + this.queueIdx = fields.queueIdx; + this.schedule = fields.schedule; + this.maxContainerParamsLen = fields.maxContainerParamsLen; + this.containerParamsHash = fields.containerParamsHash; + this.containerParams = fields.containerParams; + this.lastExecutionTimestamp = fields.lastExecutionTimestamp; + this.lastSuccessfulExecutionTimestamp = + fields.lastSuccessfulExecutionTimestamp; + this.nextAllowedTimestamp = fields.nextAllowedTimestamp; + this.ebuf = fields.ebuf; + } + + static async fetch( + program: SwitchboardProgram, + address: PublicKey, + programId: PublicKey = program.attestationProgramId + ): Promise { + const info = await program.connection.getAccountInfo(address); + + if (info === null) { + return null; + } + if (!info.owner.equals(programId)) { + throw new Error("account doesn't belong to this program"); + } + + return this.decode(info.data); + } + + static async fetchMultiple( + program: SwitchboardProgram, + addresses: PublicKey[], + programId: PublicKey = program.attestationProgramId + ): Promise> { + const infos = await program.connection.getMultipleAccountsInfo(addresses); + + return infos.map((info) => { + if (info === null) { + return null; + } + if (!info.owner.equals(programId)) { + throw new Error("account doesn't belong to this program"); + } + + return this.decode(info.data); + }); + } + + static decode(data: Buffer): FunctionRoutineAccountData { + if (!data.slice(0, 8).equals(FunctionRoutineAccountData.discriminator)) { + throw new Error("invalid account discriminator"); + } + + const dec = FunctionRoutineAccountData.layout.decode(data.slice(8)); + + return new FunctionRoutineAccountData({ + name: dec.name, + metadata: dec.metadata, + createdAt: dec.createdAt, + updatedAt: dec.updatedAt, + isDisabled: types.ResourceLevel.fromDecoded(dec.isDisabled), + status: types.RoutineStatus.fromDecoded(dec.status), + errorStatus: dec.errorStatus, + enclaveSigner: dec.enclaveSigner, + verifier: dec.verifier, + bounty: dec.bounty, + authority: dec.authority, + payer: dec.payer, + function: dec.function, + attestationQueue: dec.attestationQueue, + escrowWallet: dec.escrowWallet, + escrowTokenWallet: dec.escrowTokenWallet, + queueIdx: dec.queueIdx, + schedule: dec.schedule, + maxContainerParamsLen: dec.maxContainerParamsLen, + containerParamsHash: dec.containerParamsHash, + containerParams: new Uint8Array( + dec.containerParams.buffer, + dec.containerParams.byteOffset, + dec.containerParams.length + ), + lastExecutionTimestamp: dec.lastExecutionTimestamp, + lastSuccessfulExecutionTimestamp: dec.lastSuccessfulExecutionTimestamp, + nextAllowedTimestamp: dec.nextAllowedTimestamp, + ebuf: dec.ebuf, + }); + } + + toJSON(): FunctionRoutineAccountDataJSON { + return { + name: this.name, + metadata: this.metadata, + createdAt: this.createdAt.toString(), + updatedAt: this.updatedAt.toString(), + isDisabled: this.isDisabled.toJSON(), + status: this.status.toJSON(), + errorStatus: this.errorStatus, + enclaveSigner: this.enclaveSigner.toString(), + verifier: this.verifier.toString(), + bounty: this.bounty.toString(), + authority: this.authority.toString(), + payer: this.payer.toString(), + function: this.function.toString(), + attestationQueue: this.attestationQueue.toString(), + escrowWallet: this.escrowWallet.toString(), + escrowTokenWallet: this.escrowTokenWallet.toString(), + queueIdx: this.queueIdx, + schedule: this.schedule, + maxContainerParamsLen: this.maxContainerParamsLen, + containerParamsHash: this.containerParamsHash, + containerParams: Array.from(this.containerParams.values()), + lastExecutionTimestamp: this.lastExecutionTimestamp.toString(), + lastSuccessfulExecutionTimestamp: + this.lastSuccessfulExecutionTimestamp.toString(), + nextAllowedTimestamp: this.nextAllowedTimestamp.toString(), + ebuf: this.ebuf, + }; + } + + static fromJSON( + obj: FunctionRoutineAccountDataJSON + ): FunctionRoutineAccountData { + return new FunctionRoutineAccountData({ + name: obj.name, + metadata: obj.metadata, + createdAt: new BN(obj.createdAt), + updatedAt: new BN(obj.updatedAt), + isDisabled: types.ResourceLevel.fromJSON(obj.isDisabled), + status: types.RoutineStatus.fromJSON(obj.status), + errorStatus: obj.errorStatus, + enclaveSigner: new PublicKey(obj.enclaveSigner), + verifier: new PublicKey(obj.verifier), + bounty: new BN(obj.bounty), + authority: new PublicKey(obj.authority), + payer: new PublicKey(obj.payer), + function: new PublicKey(obj.function), + attestationQueue: new PublicKey(obj.attestationQueue), + escrowWallet: new PublicKey(obj.escrowWallet), + escrowTokenWallet: new PublicKey(obj.escrowTokenWallet), + queueIdx: obj.queueIdx, + schedule: obj.schedule, + maxContainerParamsLen: obj.maxContainerParamsLen, + containerParamsHash: obj.containerParamsHash, + containerParams: Uint8Array.from(obj.containerParams), + lastExecutionTimestamp: new BN(obj.lastExecutionTimestamp), + lastSuccessfulExecutionTimestamp: new BN( + obj.lastSuccessfulExecutionTimestamp + ), + nextAllowedTimestamp: new BN(obj.nextAllowedTimestamp), + ebuf: obj.ebuf, + }); + } +} diff --git a/javascript/solana.js/src/generated/attestation-program/accounts/SwitchboardWallet.ts b/javascript/solana.js/src/generated/attestation-program/accounts/SwitchboardWallet.ts index 2c1fc5046..fd73f6ccc 100644 --- a/javascript/solana.js/src/generated/attestation-program/accounts/SwitchboardWallet.ts +++ b/javascript/solana.js/src/generated/attestation-program/accounts/SwitchboardWallet.ts @@ -6,14 +6,26 @@ import { Connection, PublicKey } from "@solana/web3.js"; import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars export interface SwitchboardWalletFields { + /** The bump used to derive the PDA. */ bump: number; + /** Flag dictating whether the wallet has been initialized already. */ initialized: number; + /** The public key of the mint used for this wallet. */ mint: PublicKey; + /** The attestation queue pubkey. */ attestationQueue: PublicKey; + /** The wallet authority that is permitted to make account changes. */ authority: PublicKey; + /** The name of the wallet for easier identification. */ name: Array; + /** The number of resources tied to this wallet. */ resourceCount: number; + /** + * The pubkey of the account that is permitted to withdraw funds from the wallet. + * Setting this to the default pubkey will lock deposited funds. + */ withdrawAuthority: PublicKey; + /** The associated token account pubkey. */ tokenWallet: PublicKey; resources: Array; resourcesMaxLen: number; @@ -22,14 +34,26 @@ export interface SwitchboardWalletFields { } export interface SwitchboardWalletJSON { + /** The bump used to derive the PDA. */ bump: number; + /** Flag dictating whether the wallet has been initialized already. */ initialized: number; + /** The public key of the mint used for this wallet. */ mint: string; + /** The attestation queue pubkey. */ attestationQueue: string; + /** The wallet authority that is permitted to make account changes. */ authority: string; + /** The name of the wallet for easier identification. */ name: Array; + /** The number of resources tied to this wallet. */ resourceCount: number; + /** + * The pubkey of the account that is permitted to withdraw funds from the wallet. + * Setting this to the default pubkey will lock deposited funds. + */ withdrawAuthority: string; + /** The associated token account pubkey. */ tokenWallet: string; resources: Array; resourcesMaxLen: number; @@ -38,14 +62,26 @@ export interface SwitchboardWalletJSON { } export class SwitchboardWallet { + /** The bump used to derive the PDA. */ readonly bump: number; + /** Flag dictating whether the wallet has been initialized already. */ readonly initialized: number; + /** The public key of the mint used for this wallet. */ readonly mint: PublicKey; + /** The attestation queue pubkey. */ readonly attestationQueue: PublicKey; + /** The wallet authority that is permitted to make account changes. */ readonly authority: PublicKey; + /** The name of the wallet for easier identification. */ readonly name: Array; + /** The number of resources tied to this wallet. */ readonly resourceCount: number; + /** + * The pubkey of the account that is permitted to withdraw funds from the wallet. + * Setting this to the default pubkey will lock deposited funds. + */ readonly withdrawAuthority: PublicKey; + /** The associated token account pubkey. */ readonly tokenWallet: PublicKey; readonly resources: Array; readonly resourcesMaxLen: number; diff --git a/javascript/solana.js/src/generated/attestation-program/accounts/VerifierAccountData.ts b/javascript/solana.js/src/generated/attestation-program/accounts/VerifierAccountData.ts index e28fab0ad..71ec48b87 100644 --- a/javascript/solana.js/src/generated/attestation-program/accounts/VerifierAccountData.ts +++ b/javascript/solana.js/src/generated/attestation-program/accounts/VerifierAccountData.ts @@ -15,7 +15,7 @@ export interface VerifierAccountDataFields { /** The unix timestamp when the quote was created. */ createdAt: BN; /** Whether the quote is located on the AttestationQueues buffer. */ - isOnQueue: boolean; + isOnQueue: number; /** The last time the quote heartbeated on-chain. */ lastHeartbeat: BN; /** @@ -42,7 +42,7 @@ export interface VerifierAccountDataJSON { /** The unix timestamp when the quote was created. */ createdAt: string; /** Whether the quote is located on the AttestationQueues buffer. */ - isOnQueue: boolean; + isOnQueue: number; /** The last time the quote heartbeated on-chain. */ lastHeartbeat: string; /** @@ -69,7 +69,7 @@ export class VerifierAccountData { /** The unix timestamp when the quote was created. */ readonly createdAt: BN; /** Whether the quote is located on the AttestationQueues buffer. */ - readonly isOnQueue: boolean; + readonly isOnQueue: number; /** The last time the quote heartbeated on-chain. */ readonly lastHeartbeat: BN; /** @@ -94,7 +94,7 @@ export class VerifierAccountData { borsh.publicKey("authority"), borsh.publicKey("attestationQueue"), borsh.i64("createdAt"), - borsh.bool("isOnQueue"), + borsh.u8("isOnQueue"), borsh.i64("lastHeartbeat"), borsh.publicKey("rewardEscrow"), borsh.publicKey("stakeWallet"), diff --git a/javascript/solana.js/src/generated/attestation-program/accounts/index.ts b/javascript/solana.js/src/generated/attestation-program/accounts/index.ts index cb7def399..220feca28 100644 --- a/javascript/solana.js/src/generated/attestation-program/accounts/index.ts +++ b/javascript/solana.js/src/generated/attestation-program/accounts/index.ts @@ -23,6 +23,11 @@ export type { FunctionRequestAccountDataJSON, } from "./FunctionRequestAccountData.js"; export { FunctionRequestAccountData } from "./FunctionRequestAccountData.js"; +export type { + FunctionRoutineAccountDataFields, + FunctionRoutineAccountDataJSON, +} from "./FunctionRoutineAccountData.js"; +export { FunctionRoutineAccountData } from "./FunctionRoutineAccountData.js"; export type { SwitchboardWalletFields, SwitchboardWalletJSON, diff --git a/javascript/solana.js/src/generated/attestation-program/errors/custom.ts b/javascript/solana.js/src/generated/attestation-program/errors/custom.ts index a0fa54f6b..d477af61a 100644 --- a/javascript/solana.js/src/generated/attestation-program/errors/custom.ts +++ b/javascript/solana.js/src/generated/attestation-program/errors/custom.ts @@ -41,7 +41,18 @@ export type CustomError = | RequestAlreadyInitialized | AccountCloseNotPermitted | AccountCloseNotReady - | FunctionRequestNotReady; + | FunctionRequestNotReady + | InvalidParamsHash + | RequestInvalidStatus + | ContainerParamsTooLong + | RoutineDisabled + | FunctionRoutinesDisabled + | ConfigParameterLocked + | RequestBufferFull + | RequestRoundNotActive + | EmptyEscrow + | MissingSbWalletAuthoritySigner + | RequestRoundAlreadyClosed; export class GenericError extends Error { static readonly code = 6000; @@ -89,9 +100,13 @@ export class InsufficientQueue extends Error { static readonly code = 6004; readonly code = 6004; readonly name = "InsufficientQueue"; + readonly msg = + "The provided queue is empty and has no verifier oracles heartbeating on-chain."; constructor(readonly logs?: string[]) { - super("6004: "); + super( + "6004: The provided queue is empty and has no verifier oracles heartbeating on-chain." + ); } } @@ -245,9 +260,13 @@ export class IncorrectObservedTime extends Error { static readonly code = 6018; readonly code = 6018; readonly name = "IncorrectObservedTime"; + readonly msg = + "The provided timestamp is not within the expected range. This may be indicative of an unhealthy enclave."; constructor(readonly logs?: string[]) { - super("6018: "); + super( + "6018: The provided timestamp is not within the expected range. This may be indicative of an unhealthy enclave." + ); } } @@ -285,9 +304,13 @@ export class IncorrectMrEnclave extends Error { static readonly code = 6022; readonly code = 6022; readonly name = "IncorrectMrEnclave"; + readonly msg = + "The provided mr_enclave measurement did not match a value in its enclave settings. If you recently modified your function container, you may need to update the measurement in your FunctionAccount config."; constructor(readonly logs?: string[]) { - super("6022: "); + super( + "6022: The provided mr_enclave measurement did not match a value in its enclave settings. If you recently modified your function container, you may need to update the measurement in your FunctionAccount config." + ); } } @@ -377,10 +400,10 @@ export class RequestExpired extends Error { static readonly code = 6030; readonly code = 6030; readonly name = "RequestExpired"; - readonly msg = "The requests expirationSlot has expired"; + readonly msg = "The requests expiration_slot has expired"; constructor(readonly logs?: string[]) { - super("6030: The requests expirationSlot has expired"); + super("6030: The requests expiration_slot has expired"); } } @@ -521,6 +544,149 @@ export class FunctionRequestNotReady extends Error { } } +export class InvalidParamsHash extends Error { + static readonly code = 6042; + readonly code = 6042; + readonly name = "InvalidParamsHash"; + readonly msg = + "The container params hash does not match the expected hash on-chain. The parameters may have been modified in-flight; the assigned oracle may need to pickup the account change before re-verifying the function."; + + constructor(readonly logs?: string[]) { + super( + "6042: The container params hash does not match the expected hash on-chain. The parameters may have been modified in-flight; the assigned oracle may need to pickup the account change before re-verifying the function." + ); + } +} + +export class RequestInvalidStatus extends Error { + static readonly code = 6043; + readonly code = 6043; + readonly name = "RequestInvalidStatus"; + + constructor(readonly logs?: string[]) { + super("6043: "); + } +} + +export class ContainerParamsTooLong extends Error { + static readonly code = 6044; + readonly code = 6044; + readonly name = "ContainerParamsTooLong"; + readonly msg = + "Please ensure your parameters length is <= your account max length"; + + constructor(readonly logs?: string[]) { + super( + "6044: Please ensure your parameters length is <= your account max length" + ); + } +} + +export class RoutineDisabled extends Error { + static readonly code = 6045; + readonly code = 6045; + readonly name = "RoutineDisabled"; + readonly msg = + "The routine has been disabled. Please check the routin's is_disabled status for more information."; + + constructor(readonly logs?: string[]) { + super( + "6045: The routine has been disabled. Please check the routin's is_disabled status for more information." + ); + } +} + +export class FunctionRoutinesDisabled extends Error { + static readonly code = 6046; + readonly code = 6046; + readonly name = "FunctionRoutinesDisabled"; + readonly msg = + "The function authority has disabled routine execution for this function"; + + constructor(readonly logs?: string[]) { + super( + "6046: The function authority has disabled routine execution for this function" + ); + } +} + +export class ConfigParameterLocked extends Error { + static readonly code = 6047; + readonly code = 6047; + readonly name = "ConfigParameterLocked"; + readonly msg = + "The configuration parameter has been locked and cannot be changed"; + + constructor(readonly logs?: string[]) { + super( + "6047: The configuration parameter has been locked and cannot be changed" + ); + } +} + +export class RequestBufferFull extends Error { + static readonly code = 6048; + readonly code = 6048; + readonly name = "RequestBufferFull"; + + constructor(readonly logs?: string[]) { + super("6048: "); + } +} + +export class RequestRoundNotActive extends Error { + static readonly code = 6049; + readonly code = 6049; + readonly name = "RequestRoundNotActive"; + readonly msg = "The request does not have an active round to verify"; + + constructor(readonly logs?: string[]) { + super("6049: The request does not have an active round to verify"); + } +} + +export class EmptyEscrow extends Error { + static readonly code = 6050; + readonly code = 6050; + readonly name = "EmptyEscrow"; + readonly msg = + "The resources escrow token account has a balance of 0 and the queue reward is greater than 0"; + + constructor(readonly logs?: string[]) { + super( + "6050: The resources escrow token account has a balance of 0 and the queue reward is greater than 0" + ); + } +} + +export class MissingSbWalletAuthoritySigner extends Error { + static readonly code = 6051; + readonly code = 6051; + readonly name = "MissingSbWalletAuthoritySigner"; + readonly msg = + "The SwitchboardWallet authority must sign this request in order to use its escrow wallet"; + + constructor(readonly logs?: string[]) { + super( + "6051: The SwitchboardWallet authority must sign this request in order to use its escrow wallet" + ); + } +} + +export class RequestRoundAlreadyClosed extends Error { + static readonly code = 6052; + readonly code = 6052; + readonly name = "RequestRoundAlreadyClosed"; + readonly msg = + "The verifier is attempting to respond to an already closed request round with the same request_slot"; + + constructor(readonly logs?: string[]) { + super( + "6052: The verifier is attempting to respond to an already closed request round with the same request_slot" + ); + } +} + export function fromCode(code: number, logs?: string[]): CustomError | null { switch (code) { case 6000: @@ -607,6 +773,28 @@ export function fromCode(code: number, logs?: string[]): CustomError | null { return new AccountCloseNotReady(logs); case 6041: return new FunctionRequestNotReady(logs); + case 6042: + return new InvalidParamsHash(logs); + case 6043: + return new RequestInvalidStatus(logs); + case 6044: + return new ContainerParamsTooLong(logs); + case 6045: + return new RoutineDisabled(logs); + case 6046: + return new FunctionRoutinesDisabled(logs); + case 6047: + return new ConfigParameterLocked(logs); + case 6048: + return new RequestBufferFull(logs); + case 6049: + return new RequestRoundNotActive(logs); + case 6050: + return new EmptyEscrow(logs); + case 6051: + return new MissingSbWalletAuthoritySigner(logs); + case 6052: + return new RequestRoundAlreadyClosed(logs); } return null; diff --git a/javascript/solana.js/src/generated/attestation-program/instructions/functionInit.ts b/javascript/solana.js/src/generated/attestation-program/instructions/functionInit.ts index c6cf2bf6f..0bf3db326 100644 --- a/javascript/solana.js/src/generated/attestation-program/instructions/functionInit.ts +++ b/javascript/solana.js/src/generated/attestation-program/instructions/functionInit.ts @@ -16,9 +16,9 @@ export interface FunctionInitAccounts { authority: PublicKey; attestationQueue: PublicKey; payer: PublicKey; - wallet: PublicKey; - walletAuthority: PublicKey; - tokenWallet: PublicKey; + escrowWallet: PublicKey; + escrowWalletAuthority: PublicKey; + escrowTokenWallet: PublicKey; mint: PublicKey; tokenProgram: PublicKey; associatedTokenProgram: PublicKey; @@ -40,9 +40,13 @@ export function functionInit( { pubkey: accounts.authority, isSigner: false, isWritable: false }, { pubkey: accounts.attestationQueue, isSigner: false, isWritable: false }, { pubkey: accounts.payer, isSigner: true, isWritable: true }, - { pubkey: accounts.wallet, isSigner: false, isWritable: true }, - { pubkey: accounts.walletAuthority, isSigner: true, isWritable: false }, - { pubkey: accounts.tokenWallet, isSigner: false, isWritable: true }, + { pubkey: accounts.escrowWallet, isSigner: false, isWritable: true }, + { + pubkey: accounts.escrowWalletAuthority, + isSigner: true, + isWritable: false, + }, + { pubkey: accounts.escrowTokenWallet, isSigner: false, isWritable: true }, { pubkey: accounts.mint, isSigner: false, isWritable: false }, { pubkey: accounts.tokenProgram, isSigner: false, isWritable: false }, { diff --git a/javascript/solana.js/src/generated/attestation-program/instructions/functionRequestInit.ts b/javascript/solana.js/src/generated/attestation-program/instructions/functionRequestInit.ts index 323235c9b..72bc5b605 100644 --- a/javascript/solana.js/src/generated/attestation-program/instructions/functionRequestInit.ts +++ b/javascript/solana.js/src/generated/attestation-program/instructions/functionRequestInit.ts @@ -29,6 +29,7 @@ export const layout = borsh.struct([ types.FunctionRequestInitParams.layout("params"), ]); +/** Request Actions */ export function functionRequestInit( program: SwitchboardProgram, args: FunctionRequestInitArgs, diff --git a/javascript/solana.js/src/generated/attestation-program/instructions/functionRequestVerify.ts b/javascript/solana.js/src/generated/attestation-program/instructions/functionRequestVerify.ts index 1cef10969..21d75ed16 100644 --- a/javascript/solana.js/src/generated/attestation-program/instructions/functionRequestVerify.ts +++ b/javascript/solana.js/src/generated/attestation-program/instructions/functionRequestVerify.ts @@ -29,6 +29,33 @@ export const layout = borsh.struct([ types.FunctionRequestVerifyParams.layout("params"), ]); +/** + * Verifies a function request was executed within an enclave and sets + * the enclave signer on the request account for downstream instructions to verify. + * + * # Errors + * + * * `InsufficientQueue` - If the attestation queue has no active verifier oracles + * * `InvalidQuote` - If the verifier oracle has an invalid or expired quote + * * `IncorrectMrEnclave` - If the verifiers mr_enclave is not found in the attestation queue's enclave set + * + * * `RequestRoundNotActive` - If there is no active round for the request + * * `FunctionRequestNotReady` - If the request is not active yet + * * `UserRequestsDisabled` - If the function has disabled routines + * * `FunctionNotReady` - If the function status is not Active + * * `InvalidMrEnclave` - If the measured mr_enclave value is not null + * * `MrEnclavesEmpty` - If the function has 0 mr_enclaves whitelisted + * * `IncorrectMrEnclave` - If the measured mr_enclave is not found in the functions enclave set + * + * * `InvalidRequest` - If the provided params.request_slot does not match the active round request_slot + * * `IllegalExecuteAttempt` - If the request slot is 0 or greater than the current slot + * + * * `InvalidEscrow` - If the function escrow was provided but incorrect. + * * `MissingFunctionEscrow` - If the function escrow was not provided but required because func.routines_dev_fee > 0 + * * `IncorrectObservedTime` - If the oracles observed time has drifted by 20 seconds + * * `InvalidParamsHash` If the container params hash is not the same as the routine params hash. Used to mitigate malicous RPCs. + * + */ export function functionRequestVerify( program: SwitchboardProgram, args: FunctionRequestVerifyArgs, diff --git a/javascript/solana.js/src/generated/attestation-program/instructions/functionRoutineDisable.ts b/javascript/solana.js/src/generated/attestation-program/instructions/functionRoutineDisable.ts new file mode 100644 index 000000000..8dcdcce6a --- /dev/null +++ b/javascript/solana.js/src/generated/attestation-program/instructions/functionRoutineDisable.ts @@ -0,0 +1,51 @@ +import type { SwitchboardProgram } from "../../../SwitchboardProgram.js"; +import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars + +import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars +import type { AccountMeta, PublicKey } from "@solana/web3.js"; +import { TransactionInstruction } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars +import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars + +export interface FunctionRoutineDisableArgs { + params: types.FunctionRoutineDisableParamsFields; +} + +export interface FunctionRoutineDisableAccounts { + routine: PublicKey; + function: PublicKey; + attestationQueue: PublicKey; + authority: PublicKey; + functionAuthority: PublicKey; + queueAuthority: PublicKey; +} + +export const layout = borsh.struct([ + types.FunctionRoutineDisableParams.layout("params"), +]); + +export function functionRoutineDisable( + program: SwitchboardProgram, + args: FunctionRoutineDisableArgs, + accounts: FunctionRoutineDisableAccounts, + programId: PublicKey = program.attestationProgramId +) { + const keys: Array = [ + { pubkey: accounts.routine, isSigner: false, isWritable: true }, + { pubkey: accounts.function, isSigner: false, isWritable: false }, + { pubkey: accounts.attestationQueue, isSigner: false, isWritable: false }, + { pubkey: accounts.authority, isSigner: true, isWritable: false }, + { pubkey: accounts.functionAuthority, isSigner: true, isWritable: false }, + { pubkey: accounts.queueAuthority, isSigner: true, isWritable: false }, + ]; + const identifier = Buffer.from([8, 89, 112, 206, 251, 129, 150, 18]); + const buffer = Buffer.alloc(1000); + const len = layout.encode( + { + params: types.FunctionRoutineDisableParams.toEncodable(args.params), + }, + buffer + ); + const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len); + const ix = new TransactionInstruction({ keys, programId, data }); + return ix; +} diff --git a/javascript/solana.js/src/generated/attestation-program/instructions/functionRoutineInit.ts b/javascript/solana.js/src/generated/attestation-program/instructions/functionRoutineInit.ts new file mode 100644 index 000000000..2794114d0 --- /dev/null +++ b/javascript/solana.js/src/generated/attestation-program/instructions/functionRoutineInit.ts @@ -0,0 +1,82 @@ +import type { SwitchboardProgram } from "../../../SwitchboardProgram.js"; +import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars + +import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars +import type { AccountMeta, PublicKey } from "@solana/web3.js"; +import { TransactionInstruction } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars +import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars + +export interface FunctionRoutineInitArgs { + params: types.FunctionRoutineInitParamsFields; +} + +export interface FunctionRoutineInitAccounts { + routine: PublicKey; + authority: PublicKey; + function: PublicKey; + functionAuthority: PublicKey; + escrowWallet: PublicKey; + escrowWalletAuthority: PublicKey; + escrowTokenWallet: PublicKey; + mint: PublicKey; + attestationQueue: PublicKey; + payer: PublicKey; + systemProgram: PublicKey; + tokenProgram: PublicKey; + associatedTokenProgram: PublicKey; +} + +export const layout = borsh.struct([ + types.FunctionRoutineInitParams.layout("params"), +]); + +/** + * Routine Actions + * Initializes a Function routine account + * + * # Errors + * + * * `MissingSbWalletAuthoritySigner` - If the provided SbWallet authority does not match the routine + * authority and the wallet authority did not sign the transaction. + */ +export function functionRoutineInit( + program: SwitchboardProgram, + args: FunctionRoutineInitArgs, + accounts: FunctionRoutineInitAccounts, + programId: PublicKey = program.attestationProgramId +) { + const keys: Array = [ + { pubkey: accounts.routine, isSigner: true, isWritable: true }, + { pubkey: accounts.authority, isSigner: false, isWritable: false }, + { pubkey: accounts.function, isSigner: false, isWritable: true }, + { pubkey: accounts.functionAuthority, isSigner: true, isWritable: false }, + { pubkey: accounts.escrowWallet, isSigner: false, isWritable: true }, + { + pubkey: accounts.escrowWalletAuthority, + isSigner: true, + isWritable: false, + }, + { pubkey: accounts.escrowTokenWallet, isSigner: false, isWritable: true }, + { pubkey: accounts.mint, isSigner: false, isWritable: false }, + { pubkey: accounts.attestationQueue, isSigner: false, isWritable: false }, + { pubkey: accounts.payer, isSigner: true, isWritable: true }, + { pubkey: accounts.systemProgram, isSigner: false, isWritable: false }, + { pubkey: accounts.tokenProgram, isSigner: false, isWritable: false }, + { + pubkey: accounts.associatedTokenProgram, + isSigner: false, + isWritable: false, + }, + ]; + const identifier = Buffer.from([70, 25, 243, 23, 253, 78, 27, 169]); + const buffer = Buffer.alloc(1000); + const len = layout.encode( + { + params: types.FunctionRoutineInitParams.toEncodable(args.params), + }, + buffer + ); + const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len); + const ix = new TransactionInstruction({ keys, programId, data }); + return ix; +} diff --git a/javascript/solana.js/src/generated/attestation-program/instructions/functionRoutineSetConfig.ts b/javascript/solana.js/src/generated/attestation-program/instructions/functionRoutineSetConfig.ts new file mode 100644 index 000000000..71ba78c14 --- /dev/null +++ b/javascript/solana.js/src/generated/attestation-program/instructions/functionRoutineSetConfig.ts @@ -0,0 +1,43 @@ +import type { SwitchboardProgram } from "../../../SwitchboardProgram.js"; +import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars + +import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars +import type { AccountMeta, PublicKey } from "@solana/web3.js"; +import { TransactionInstruction } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars +import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars + +export interface FunctionRoutineSetConfigArgs { + params: types.FunctionRoutineSetConfigParamsFields; +} + +export interface FunctionRoutineSetConfigAccounts { + routine: PublicKey; + authority: PublicKey; +} + +export const layout = borsh.struct([ + types.FunctionRoutineSetConfigParams.layout("params"), +]); + +export function functionRoutineSetConfig( + program: SwitchboardProgram, + args: FunctionRoutineSetConfigArgs, + accounts: FunctionRoutineSetConfigAccounts, + programId: PublicKey = program.attestationProgramId +) { + const keys: Array = [ + { pubkey: accounts.routine, isSigner: false, isWritable: true }, + { pubkey: accounts.authority, isSigner: true, isWritable: false }, + ]; + const identifier = Buffer.from([171, 170, 164, 53, 255, 71, 245, 79]); + const buffer = Buffer.alloc(1000); + const len = layout.encode( + { + params: types.FunctionRoutineSetConfigParams.toEncodable(args.params), + }, + buffer + ); + const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len); + const ix = new TransactionInstruction({ keys, programId, data }); + return ix; +} diff --git a/javascript/solana.js/src/generated/attestation-program/instructions/functionRoutineVerify.ts b/javascript/solana.js/src/generated/attestation-program/instructions/functionRoutineVerify.ts new file mode 100644 index 000000000..3019943c1 --- /dev/null +++ b/javascript/solana.js/src/generated/attestation-program/instructions/functionRoutineVerify.ts @@ -0,0 +1,99 @@ +import type { SwitchboardProgram } from "../../../SwitchboardProgram.js"; +import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars + +import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars +import type { AccountMeta, PublicKey } from "@solana/web3.js"; +import { TransactionInstruction } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars +import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars + +export interface FunctionRoutineVerifyArgs { + params: types.FunctionRoutineVerifyParamsFields; +} + +export interface FunctionRoutineVerifyAccounts { + routine: PublicKey; + functionEnclaveSigner: PublicKey; + escrowWallet: PublicKey; + escrowTokenWallet: PublicKey; + function: PublicKey; + functionEscrowTokenWallet: PublicKey; + verifierQuote: PublicKey; + verifierEnclaveSigner: PublicKey; + verifierPermission: PublicKey; + attestationQueue: PublicKey; + receiver: PublicKey; + tokenProgram: PublicKey; +} + +export const layout = borsh.struct([ + types.FunctionRoutineVerifyParams.layout("params"), +]); + +/** + * Verifies a function routine was executed within an enclave and sets + * the enclave signer on the routine account for downstream instructions to verify. + * + * # Errors + * + * * `InsufficientQueue` - If the attestation queue has no active verifier oracles + * * `InvalidQuote` - If the verifier oracle has an invalid or expired quote + * * `IncorrectMrEnclave` - If the verifiers mr_enclave is not found in the attestation queue's enclave set + * * `IllegalVerifier` - If the incorrect verifier has responded and the routine is less than 30 seconds stale. + * + * * `RoutineDisabled` - If the routine has been disabled + * * `FunctionRoutinesDisabled` - If the function has disabled routines + * * `FunctionNotReady` - If the function status is not Active + * * `InvalidMrEnclave` - If the measured mr_enclave value is not null + * * `MrEnclavesEmpty` - If the function has 0 mr_enclaves whitelisted + * * `IncorrectMrEnclave` - If the measured mr_enclave is not found in the functions enclave set + * + * * `InvalidEscrow` - If the function escrow was provided but incorrect. + * * `MissingFunctionEscrow` - If the function escrow was not provided but required because func.routines_dev_fee > 0 + * * `IncorrectObservedTime` - If the oracles observed time has drifted by 20 seconds + * * `InvalidParamsHash` If the container params hash is not the same as the routine params hash. Used to mitigate malicous RPCs. + * + */ +export function functionRoutineVerify( + program: SwitchboardProgram, + args: FunctionRoutineVerifyArgs, + accounts: FunctionRoutineVerifyAccounts, + programId: PublicKey = program.attestationProgramId +) { + const keys: Array = [ + { pubkey: accounts.routine, isSigner: false, isWritable: true }, + { + pubkey: accounts.functionEnclaveSigner, + isSigner: true, + isWritable: false, + }, + { pubkey: accounts.escrowWallet, isSigner: false, isWritable: true }, + { pubkey: accounts.escrowTokenWallet, isSigner: false, isWritable: true }, + { pubkey: accounts.function, isSigner: false, isWritable: true }, + { + pubkey: accounts.functionEscrowTokenWallet, + isSigner: false, + isWritable: true, + }, + { pubkey: accounts.verifierQuote, isSigner: false, isWritable: false }, + { + pubkey: accounts.verifierEnclaveSigner, + isSigner: true, + isWritable: false, + }, + { pubkey: accounts.verifierPermission, isSigner: false, isWritable: false }, + { pubkey: accounts.attestationQueue, isSigner: false, isWritable: false }, + { pubkey: accounts.receiver, isSigner: false, isWritable: true }, + { pubkey: accounts.tokenProgram, isSigner: false, isWritable: false }, + ]; + const identifier = Buffer.from([138, 151, 43, 227, 196, 155, 245, 105]); + const buffer = Buffer.alloc(1000); + const len = layout.encode( + { + params: types.FunctionRoutineVerifyParams.toEncodable(args.params), + }, + buffer + ); + const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len); + const ix = new TransactionInstruction({ keys, programId, data }); + return ix; +} diff --git a/javascript/solana.js/src/generated/attestation-program/instructions/functionVerify.ts b/javascript/solana.js/src/generated/attestation-program/instructions/functionVerify.ts index a7f2c8758..4b95b0649 100644 --- a/javascript/solana.js/src/generated/attestation-program/instructions/functionVerify.ts +++ b/javascript/solana.js/src/generated/attestation-program/instructions/functionVerify.ts @@ -27,6 +27,25 @@ export const layout = borsh.struct([ types.FunctionVerifyParams.layout("params"), ]); +/** + * Verifies a function was executed within an enclave and sets the enclave signer + * on the function account for downstream instructions to verify. + * + * # Errors + * + * * `InsufficientQueue` - If the attestation queue has no active verifier oracles + * * `InvalidQuote` - If the verifier oracle has an invalid or expired quote + * * `IncorrectMrEnclave` - If the verifiers mr_enclave is not found in the attestation queue's enclave set + * * `IllegalVerifier` - If the incorrect verifier has responded and the routine is less than 30 seconds stale. + * + * * `FunctionNotReady` - If the function status is not Active + * * `InvalidMrEnclave` - If the measured mr_enclave value is not null + * * `MrEnclavesEmpty` - If the function has 0 mr_enclaves whitelisted + * * `IncorrectMrEnclave` - If the measured mr_enclave is not found in the functions enclave set + * + * * `IncorrectObservedTime` - If the oracles observed time has drifted by 20 seconds + * + */ export function functionVerify( program: SwitchboardProgram, args: FunctionVerifyArgs, diff --git a/javascript/solana.js/src/generated/attestation-program/instructions/index.ts b/javascript/solana.js/src/generated/attestation-program/instructions/index.ts index 78a51b95a..6756d6c3b 100644 --- a/javascript/solana.js/src/generated/attestation-program/instructions/index.ts +++ b/javascript/solana.js/src/generated/attestation-program/instructions/index.ts @@ -72,6 +72,26 @@ export type { FunctionResetEscrowArgs, } from "./functionResetEscrow.js"; export { functionResetEscrow } from "./functionResetEscrow.js"; +export type { + FunctionRoutineDisableAccounts, + FunctionRoutineDisableArgs, +} from "./functionRoutineDisable.js"; +export { functionRoutineDisable } from "./functionRoutineDisable.js"; +export type { + FunctionRoutineInitAccounts, + FunctionRoutineInitArgs, +} from "./functionRoutineInit.js"; +export { functionRoutineInit } from "./functionRoutineInit.js"; +export type { + FunctionRoutineSetConfigAccounts, + FunctionRoutineSetConfigArgs, +} from "./functionRoutineSetConfig.js"; +export { functionRoutineSetConfig } from "./functionRoutineSetConfig.js"; +export type { + FunctionRoutineVerifyAccounts, + FunctionRoutineVerifyArgs, +} from "./functionRoutineVerify.js"; +export { functionRoutineVerify } from "./functionRoutineVerify.js"; export type { FunctionSetAuthorityAccounts, FunctionSetAuthorityArgs, @@ -116,8 +136,6 @@ export type { VerifierQuoteVerifyArgs, } from "./verifierQuoteVerify.js"; export { verifierQuoteVerify } from "./verifierQuoteVerify.js"; -export type { WalletCloseAccounts, WalletCloseArgs } from "./walletClose.js"; -export { walletClose } from "./walletClose.js"; export type { WalletFundAccounts, WalletFundArgs } from "./walletFund.js"; export { walletFund } from "./walletFund.js"; export type { WalletInitAccounts, WalletInitArgs } from "./walletInit.js"; diff --git a/javascript/solana.js/src/generated/attestation-program/instructions/walletClose.ts b/javascript/solana.js/src/generated/attestation-program/instructions/walletClose.ts deleted file mode 100644 index ebb206857..000000000 --- a/javascript/solana.js/src/generated/attestation-program/instructions/walletClose.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { SwitchboardProgram } from "../../../SwitchboardProgram.js"; -import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars - -import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars -import type { AccountMeta, PublicKey } from "@solana/web3.js"; -import { TransactionInstruction } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars -import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars - -export interface WalletCloseArgs { - params: types.WalletCloseParamsFields; -} - -export interface WalletCloseAccounts { - wallet: PublicKey; - mint: PublicKey; - authority: PublicKey; - attestationQueue: PublicKey; - tokenWallet: PublicKey; - destinationWallet: PublicKey; - state: PublicKey; - solDest: PublicKey; - escrowDest: PublicKey; - tokenProgram: PublicKey; - systemProgram: PublicKey; -} - -export const layout = borsh.struct([types.WalletCloseParams.layout("params")]); - -export function walletClose( - program: SwitchboardProgram, - args: WalletCloseArgs, - accounts: WalletCloseAccounts, - programId: PublicKey = program.attestationProgramId -) { - const keys: Array = [ - { pubkey: accounts.wallet, isSigner: false, isWritable: true }, - { pubkey: accounts.mint, isSigner: false, isWritable: false }, - { pubkey: accounts.authority, isSigner: false, isWritable: false }, - { pubkey: accounts.attestationQueue, isSigner: false, isWritable: false }, - { pubkey: accounts.tokenWallet, isSigner: false, isWritable: true }, - { pubkey: accounts.destinationWallet, isSigner: false, isWritable: true }, - { pubkey: accounts.state, isSigner: false, isWritable: false }, - { pubkey: accounts.solDest, isSigner: false, isWritable: false }, - { pubkey: accounts.escrowDest, isSigner: false, isWritable: true }, - { pubkey: accounts.tokenProgram, isSigner: false, isWritable: false }, - { pubkey: accounts.systemProgram, isSigner: false, isWritable: false }, - ]; - const identifier = Buffer.from([88, 153, 120, 100, 41, 170, 2, 43]); - const buffer = Buffer.alloc(1000); - const len = layout.encode( - { - params: types.WalletCloseParams.toEncodable(args.params), - }, - buffer - ); - const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len); - const ix = new TransactionInstruction({ keys, programId, data }); - return ix; -} diff --git a/javascript/solana.js/src/generated/attestation-program/instructions/walletInit.ts b/javascript/solana.js/src/generated/attestation-program/instructions/walletInit.ts index 504d85c10..bcbe19483 100644 --- a/javascript/solana.js/src/generated/attestation-program/instructions/walletInit.ts +++ b/javascript/solana.js/src/generated/attestation-program/instructions/walletInit.ts @@ -17,7 +17,6 @@ export interface WalletInitAccounts { attestationQueue: PublicKey; tokenWallet: PublicKey; payer: PublicKey; - state: PublicKey; tokenProgram: PublicKey; associatedTokenProgram: PublicKey; systemProgram: PublicKey; @@ -38,7 +37,6 @@ export function walletInit( { pubkey: accounts.attestationQueue, isSigner: false, isWritable: false }, { pubkey: accounts.tokenWallet, isSigner: false, isWritable: true }, { pubkey: accounts.payer, isSigner: true, isWritable: true }, - { pubkey: accounts.state, isSigner: false, isWritable: false }, { pubkey: accounts.tokenProgram, isSigner: false, isWritable: false }, { pubkey: accounts.associatedTokenProgram, diff --git a/javascript/solana.js/src/generated/attestation-program/types/BoolWithLock.ts b/javascript/solana.js/src/generated/attestation-program/types/BoolWithLock.ts new file mode 100644 index 000000000..a136f75da --- /dev/null +++ b/javascript/solana.js/src/generated/attestation-program/types/BoolWithLock.ts @@ -0,0 +1,150 @@ +import { SwitchboardProgram } from "../../../SwitchboardProgram.js"; +import type * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars + +import * as borsh from "@coral-xyz/borsh"; +import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars +import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars + +export interface DisabledJSON { + kind: "Disabled"; +} + +export class Disabled { + static readonly discriminator = 0; + static readonly kind = "Disabled"; + readonly discriminator = 0; + readonly kind = "Disabled"; + + toJSON(): DisabledJSON { + return { + kind: "Disabled", + }; + } + + toEncodable() { + return { + Disabled: {}, + }; + } +} + +export interface EnabledJSON { + kind: "Enabled"; +} + +export class Enabled { + static readonly discriminator = 1; + static readonly kind = "Enabled"; + readonly discriminator = 1; + readonly kind = "Enabled"; + + toJSON(): EnabledJSON { + return { + kind: "Enabled", + }; + } + + toEncodable() { + return { + Enabled: {}, + }; + } +} + +export interface DisabledLockedJSON { + kind: "DisabledLocked"; +} + +export class DisabledLocked { + static readonly discriminator = 2; + static readonly kind = "DisabledLocked"; + readonly discriminator = 2; + readonly kind = "DisabledLocked"; + + toJSON(): DisabledLockedJSON { + return { + kind: "DisabledLocked", + }; + } + + toEncodable() { + return { + DisabledLocked: {}, + }; + } +} + +export interface EnabledLockedJSON { + kind: "EnabledLocked"; +} + +export class EnabledLocked { + static readonly discriminator = 3; + static readonly kind = "EnabledLocked"; + readonly discriminator = 3; + readonly kind = "EnabledLocked"; + + toJSON(): EnabledLockedJSON { + return { + kind: "EnabledLocked", + }; + } + + toEncodable() { + return { + EnabledLocked: {}, + }; + } +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function fromDecoded(obj: any): types.BoolWithLockKind { + if (typeof obj !== "object") { + throw new Error("Invalid enum object"); + } + + if ("Disabled" in obj) { + return new Disabled(); + } + if ("Enabled" in obj) { + return new Enabled(); + } + if ("DisabledLocked" in obj) { + return new DisabledLocked(); + } + if ("EnabledLocked" in obj) { + return new EnabledLocked(); + } + + throw new Error("Invalid enum object"); +} + +export function fromJSON(obj: types.BoolWithLockJSON): types.BoolWithLockKind { + switch (obj.kind) { + case "Disabled": { + return new Disabled(); + } + case "Enabled": { + return new Enabled(); + } + case "DisabledLocked": { + return new DisabledLocked(); + } + case "EnabledLocked": { + return new EnabledLocked(); + } + } +} + +export function layout(property?: string) { + const ret = borsh.rustEnum([ + borsh.struct([], "Disabled"), + borsh.struct([], "Enabled"), + borsh.struct([], "DisabledLocked"), + borsh.struct([], "EnabledLocked"), + ]); + if (property !== undefined) { + return ret.replicate(property); + } + return ret; +} diff --git a/javascript/solana.js/src/generated/attestation-program/types/FunctionInitParams.ts b/javascript/solana.js/src/generated/attestation-program/types/FunctionInitParams.ts index 72d15b9a9..8a87bd8cd 100644 --- a/javascript/solana.js/src/generated/attestation-program/types/FunctionInitParams.ts +++ b/javascript/solana.js/src/generated/attestation-program/types/FunctionInitParams.ts @@ -6,79 +6,89 @@ import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript- import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars export interface FunctionInitParamsFields { + recentSlot: BN; + creatorSeed: Array | null; name: Uint8Array; metadata: Uint8Array; container: Uint8Array; containerRegistry: Uint8Array; version: Uint8Array; - schedule: Uint8Array; - mrEnclave: Array; - recentSlot: BN; + mrEnclave: Array | null; requestsDisabled: boolean; requestsRequireAuthorization: boolean; - requestsFee: BN; - creatorSeed: Array | null; + requestsDevFee: BN; + routinesDisabled: boolean; + routinesRequireAuthorization: boolean; + routinesDevFee: BN; } export interface FunctionInitParamsJSON { + recentSlot: string; + creatorSeed: Array | null; name: Array; metadata: Array; container: Array; containerRegistry: Array; version: Array; - schedule: Array; - mrEnclave: Array; - recentSlot: string; + mrEnclave: Array | null; requestsDisabled: boolean; requestsRequireAuthorization: boolean; - requestsFee: string; - creatorSeed: Array | null; + requestsDevFee: string; + routinesDisabled: boolean; + routinesRequireAuthorization: boolean; + routinesDevFee: string; } export class FunctionInitParams { + readonly recentSlot: BN; + readonly creatorSeed: Array | null; readonly name: Uint8Array; readonly metadata: Uint8Array; readonly container: Uint8Array; readonly containerRegistry: Uint8Array; readonly version: Uint8Array; - readonly schedule: Uint8Array; - readonly mrEnclave: Array; - readonly recentSlot: BN; + readonly mrEnclave: Array | null; readonly requestsDisabled: boolean; readonly requestsRequireAuthorization: boolean; - readonly requestsFee: BN; - readonly creatorSeed: Array | null; + readonly requestsDevFee: BN; + readonly routinesDisabled: boolean; + readonly routinesRequireAuthorization: boolean; + readonly routinesDevFee: BN; constructor(fields: FunctionInitParamsFields) { + this.recentSlot = fields.recentSlot; + this.creatorSeed = fields.creatorSeed; this.name = fields.name; this.metadata = fields.metadata; this.container = fields.container; this.containerRegistry = fields.containerRegistry; this.version = fields.version; - this.schedule = fields.schedule; this.mrEnclave = fields.mrEnclave; - this.recentSlot = fields.recentSlot; this.requestsDisabled = fields.requestsDisabled; this.requestsRequireAuthorization = fields.requestsRequireAuthorization; - this.requestsFee = fields.requestsFee; - this.creatorSeed = fields.creatorSeed; + this.requestsDevFee = fields.requestsDevFee; + this.routinesDisabled = fields.routinesDisabled; + this.routinesRequireAuthorization = fields.routinesRequireAuthorization; + this.routinesDevFee = fields.routinesDevFee; } static layout(property?: string) { return borsh.struct( [ + borsh.u64("recentSlot"), + borsh.option(borsh.array(borsh.u8(), 32), "creatorSeed"), borsh.vecU8("name"), borsh.vecU8("metadata"), borsh.vecU8("container"), borsh.vecU8("containerRegistry"), borsh.vecU8("version"), - borsh.vecU8("schedule"), - borsh.array(borsh.u8(), 32, "mrEnclave"), - borsh.u64("recentSlot"), + borsh.option(borsh.array(borsh.u8(), 32), "mrEnclave"), borsh.bool("requestsDisabled"), borsh.bool("requestsRequireAuthorization"), - borsh.u64("requestsFee"), - borsh.option(borsh.array(borsh.u8(), 32), "creatorSeed"), + borsh.u64("requestsDevFee"), + borsh.bool("routinesDisabled"), + borsh.bool("routinesRequireAuthorization"), + borsh.u64("routinesDevFee"), ], property ); @@ -87,6 +97,8 @@ export class FunctionInitParams { // eslint-disable-next-line @typescript-eslint/no-explicit-any static fromDecoded(obj: any) { return new FunctionInitParams({ + recentSlot: obj.recentSlot, + creatorSeed: obj.creatorSeed, name: new Uint8Array( obj.name.buffer, obj.name.byteOffset, @@ -112,22 +124,20 @@ export class FunctionInitParams { obj.version.byteOffset, obj.version.length ), - schedule: new Uint8Array( - obj.schedule.buffer, - obj.schedule.byteOffset, - obj.schedule.length - ), mrEnclave: obj.mrEnclave, - recentSlot: obj.recentSlot, requestsDisabled: obj.requestsDisabled, requestsRequireAuthorization: obj.requestsRequireAuthorization, - requestsFee: obj.requestsFee, - creatorSeed: obj.creatorSeed, + requestsDevFee: obj.requestsDevFee, + routinesDisabled: obj.routinesDisabled, + routinesRequireAuthorization: obj.routinesRequireAuthorization, + routinesDevFee: obj.routinesDevFee, }); } static toEncodable(fields: FunctionInitParamsFields) { return { + recentSlot: fields.recentSlot, + creatorSeed: fields.creatorSeed, name: Buffer.from( fields.name.buffer, fields.name.byteOffset, @@ -153,51 +163,51 @@ export class FunctionInitParams { fields.version.byteOffset, fields.version.length ), - schedule: Buffer.from( - fields.schedule.buffer, - fields.schedule.byteOffset, - fields.schedule.length - ), mrEnclave: fields.mrEnclave, - recentSlot: fields.recentSlot, requestsDisabled: fields.requestsDisabled, requestsRequireAuthorization: fields.requestsRequireAuthorization, - requestsFee: fields.requestsFee, - creatorSeed: fields.creatorSeed, + requestsDevFee: fields.requestsDevFee, + routinesDisabled: fields.routinesDisabled, + routinesRequireAuthorization: fields.routinesRequireAuthorization, + routinesDevFee: fields.routinesDevFee, }; } toJSON(): FunctionInitParamsJSON { return { + recentSlot: this.recentSlot.toString(), + creatorSeed: this.creatorSeed, name: Array.from(this.name.values()), metadata: Array.from(this.metadata.values()), container: Array.from(this.container.values()), containerRegistry: Array.from(this.containerRegistry.values()), version: Array.from(this.version.values()), - schedule: Array.from(this.schedule.values()), mrEnclave: this.mrEnclave, - recentSlot: this.recentSlot.toString(), requestsDisabled: this.requestsDisabled, requestsRequireAuthorization: this.requestsRequireAuthorization, - requestsFee: this.requestsFee.toString(), - creatorSeed: this.creatorSeed, + requestsDevFee: this.requestsDevFee.toString(), + routinesDisabled: this.routinesDisabled, + routinesRequireAuthorization: this.routinesRequireAuthorization, + routinesDevFee: this.routinesDevFee.toString(), }; } static fromJSON(obj: FunctionInitParamsJSON): FunctionInitParams { return new FunctionInitParams({ + recentSlot: new BN(obj.recentSlot), + creatorSeed: obj.creatorSeed, name: Uint8Array.from(obj.name), metadata: Uint8Array.from(obj.metadata), container: Uint8Array.from(obj.container), containerRegistry: Uint8Array.from(obj.containerRegistry), version: Uint8Array.from(obj.version), - schedule: Uint8Array.from(obj.schedule), mrEnclave: obj.mrEnclave, - recentSlot: new BN(obj.recentSlot), requestsDisabled: obj.requestsDisabled, requestsRequireAuthorization: obj.requestsRequireAuthorization, - requestsFee: new BN(obj.requestsFee), - creatorSeed: obj.creatorSeed, + requestsDevFee: new BN(obj.requestsDevFee), + routinesDisabled: obj.routinesDisabled, + routinesRequireAuthorization: obj.routinesRequireAuthorization, + routinesDevFee: new BN(obj.routinesDevFee), }); } diff --git a/javascript/solana.js/src/generated/attestation-program/types/FunctionRequestTriggerRound.ts b/javascript/solana.js/src/generated/attestation-program/types/FunctionRequestTriggerRound.ts index f27c2ad14..cefb15ecb 100644 --- a/javascript/solana.js/src/generated/attestation-program/types/FunctionRequestTriggerRound.ts +++ b/javascript/solana.js/src/generated/attestation-program/types/FunctionRequestTriggerRound.ts @@ -25,6 +25,7 @@ export interface FunctionRequestTriggerRoundFields { enclaveSigner: PublicKey; /** The slot when the request can first be executed. */ validAfterSlot: BN; + queueIdx: number; /** Reserved. */ ebuf: Array; } @@ -49,6 +50,7 @@ export interface FunctionRequestTriggerRoundJSON { enclaveSigner: string; /** The slot when the request can first be executed. */ validAfterSlot: string; + queueIdx: number; /** Reserved. */ ebuf: Array; } @@ -73,6 +75,7 @@ export class FunctionRequestTriggerRound { readonly enclaveSigner: PublicKey; /** The slot when the request can first be executed. */ readonly validAfterSlot: BN; + readonly queueIdx: number; /** Reserved. */ readonly ebuf: Array; @@ -85,6 +88,7 @@ export class FunctionRequestTriggerRound { this.verifier = fields.verifier; this.enclaveSigner = fields.enclaveSigner; this.validAfterSlot = fields.validAfterSlot; + this.queueIdx = fields.queueIdx; this.ebuf = fields.ebuf; } @@ -99,7 +103,8 @@ export class FunctionRequestTriggerRound { borsh.publicKey("verifier"), borsh.publicKey("enclaveSigner"), borsh.u64("validAfterSlot"), - borsh.array(borsh.u8(), 56, "ebuf"), + borsh.u32("queueIdx"), + borsh.array(borsh.u8(), 52, "ebuf"), ], property ); @@ -116,6 +121,7 @@ export class FunctionRequestTriggerRound { verifier: obj.verifier, enclaveSigner: obj.enclaveSigner, validAfterSlot: obj.validAfterSlot, + queueIdx: obj.queueIdx, ebuf: obj.ebuf, }); } @@ -130,6 +136,7 @@ export class FunctionRequestTriggerRound { verifier: fields.verifier, enclaveSigner: fields.enclaveSigner, validAfterSlot: fields.validAfterSlot, + queueIdx: fields.queueIdx, ebuf: fields.ebuf, }; } @@ -144,6 +151,7 @@ export class FunctionRequestTriggerRound { verifier: this.verifier.toString(), enclaveSigner: this.enclaveSigner.toString(), validAfterSlot: this.validAfterSlot.toString(), + queueIdx: this.queueIdx, ebuf: this.ebuf, }; } @@ -160,6 +168,7 @@ export class FunctionRequestTriggerRound { verifier: new PublicKey(obj.verifier), enclaveSigner: new PublicKey(obj.enclaveSigner), validAfterSlot: new BN(obj.validAfterSlot), + queueIdx: obj.queueIdx, ebuf: obj.ebuf, }); } diff --git a/javascript/solana.js/src/generated/attestation-program/types/FunctionRequestVerifyParams.ts b/javascript/solana.js/src/generated/attestation-program/types/FunctionRequestVerifyParams.ts index 837f6ec7a..f09c5a879 100644 --- a/javascript/solana.js/src/generated/attestation-program/types/FunctionRequestVerifyParams.ts +++ b/javascript/solana.js/src/generated/attestation-program/types/FunctionRequestVerifyParams.ts @@ -7,7 +7,7 @@ import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript export interface FunctionRequestVerifyParamsFields { observedTime: BN; - isFailure: boolean; + errorCode: number; mrEnclave: Array; requestSlot: BN; containerParamsHash: Array; @@ -15,7 +15,7 @@ export interface FunctionRequestVerifyParamsFields { export interface FunctionRequestVerifyParamsJSON { observedTime: string; - isFailure: boolean; + errorCode: number; mrEnclave: Array; requestSlot: string; containerParamsHash: Array; @@ -23,14 +23,14 @@ export interface FunctionRequestVerifyParamsJSON { export class FunctionRequestVerifyParams { readonly observedTime: BN; - readonly isFailure: boolean; + readonly errorCode: number; readonly mrEnclave: Array; readonly requestSlot: BN; readonly containerParamsHash: Array; constructor(fields: FunctionRequestVerifyParamsFields) { this.observedTime = fields.observedTime; - this.isFailure = fields.isFailure; + this.errorCode = fields.errorCode; this.mrEnclave = fields.mrEnclave; this.requestSlot = fields.requestSlot; this.containerParamsHash = fields.containerParamsHash; @@ -40,7 +40,7 @@ export class FunctionRequestVerifyParams { return borsh.struct( [ borsh.i64("observedTime"), - borsh.bool("isFailure"), + borsh.u8("errorCode"), borsh.array(borsh.u8(), 32, "mrEnclave"), borsh.u64("requestSlot"), borsh.array(borsh.u8(), 32, "containerParamsHash"), @@ -53,7 +53,7 @@ export class FunctionRequestVerifyParams { static fromDecoded(obj: any) { return new FunctionRequestVerifyParams({ observedTime: obj.observedTime, - isFailure: obj.isFailure, + errorCode: obj.errorCode, mrEnclave: obj.mrEnclave, requestSlot: obj.requestSlot, containerParamsHash: obj.containerParamsHash, @@ -63,7 +63,7 @@ export class FunctionRequestVerifyParams { static toEncodable(fields: FunctionRequestVerifyParamsFields) { return { observedTime: fields.observedTime, - isFailure: fields.isFailure, + errorCode: fields.errorCode, mrEnclave: fields.mrEnclave, requestSlot: fields.requestSlot, containerParamsHash: fields.containerParamsHash, @@ -73,7 +73,7 @@ export class FunctionRequestVerifyParams { toJSON(): FunctionRequestVerifyParamsJSON { return { observedTime: this.observedTime.toString(), - isFailure: this.isFailure, + errorCode: this.errorCode, mrEnclave: this.mrEnclave, requestSlot: this.requestSlot.toString(), containerParamsHash: this.containerParamsHash, @@ -85,7 +85,7 @@ export class FunctionRequestVerifyParams { ): FunctionRequestVerifyParams { return new FunctionRequestVerifyParams({ observedTime: new BN(obj.observedTime), - isFailure: obj.isFailure, + errorCode: obj.errorCode, mrEnclave: obj.mrEnclave, requestSlot: new BN(obj.requestSlot), containerParamsHash: obj.containerParamsHash, diff --git a/javascript/solana.js/src/generated/attestation-program/types/FunctionRoutineDisableParams.ts b/javascript/solana.js/src/generated/attestation-program/types/FunctionRoutineDisableParams.ts new file mode 100644 index 000000000..c4e54347e --- /dev/null +++ b/javascript/solana.js/src/generated/attestation-program/types/FunctionRoutineDisableParams.ts @@ -0,0 +1,57 @@ +import { SwitchboardProgram } from "../../../SwitchboardProgram.js"; +import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars + +import * as borsh from "@coral-xyz/borsh"; +import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars +import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars + +export interface FunctionRoutineDisableParamsFields { + enable: boolean | null; +} + +export interface FunctionRoutineDisableParamsJSON { + enable: boolean | null; +} + +export class FunctionRoutineDisableParams { + readonly enable: boolean | null; + + constructor(fields: FunctionRoutineDisableParamsFields) { + this.enable = fields.enable; + } + + static layout(property?: string) { + return borsh.struct([borsh.option(borsh.bool(), "enable")], property); + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + static fromDecoded(obj: any) { + return new FunctionRoutineDisableParams({ + enable: obj.enable, + }); + } + + static toEncodable(fields: FunctionRoutineDisableParamsFields) { + return { + enable: fields.enable, + }; + } + + toJSON(): FunctionRoutineDisableParamsJSON { + return { + enable: this.enable, + }; + } + + static fromJSON( + obj: FunctionRoutineDisableParamsJSON + ): FunctionRoutineDisableParams { + return new FunctionRoutineDisableParams({ + enable: obj.enable, + }); + } + + toEncodable() { + return FunctionRoutineDisableParams.toEncodable(this); + } +} diff --git a/javascript/solana.js/src/generated/attestation-program/types/FunctionRoutineInitParams.ts b/javascript/solana.js/src/generated/attestation-program/types/FunctionRoutineInitParams.ts new file mode 100644 index 000000000..b6bc2933a --- /dev/null +++ b/javascript/solana.js/src/generated/attestation-program/types/FunctionRoutineInitParams.ts @@ -0,0 +1,151 @@ +import { SwitchboardProgram } from "../../../SwitchboardProgram.js"; +import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars + +import * as borsh from "@coral-xyz/borsh"; +import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars +import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars + +export interface FunctionRoutineInitParamsFields { + name: Uint8Array | null; + metadata: Uint8Array | null; + bounty: BN | null; + schedule: Uint8Array; + maxContainerParamsLen: number | null; + containerParams: Uint8Array; +} + +export interface FunctionRoutineInitParamsJSON { + name: Array | null; + metadata: Array | null; + bounty: string | null; + schedule: Array; + maxContainerParamsLen: number | null; + containerParams: Array; +} + +export class FunctionRoutineInitParams { + readonly name: Uint8Array | null; + readonly metadata: Uint8Array | null; + readonly bounty: BN | null; + readonly schedule: Uint8Array; + readonly maxContainerParamsLen: number | null; + readonly containerParams: Uint8Array; + + constructor(fields: FunctionRoutineInitParamsFields) { + this.name = fields.name; + this.metadata = fields.metadata; + this.bounty = fields.bounty; + this.schedule = fields.schedule; + this.maxContainerParamsLen = fields.maxContainerParamsLen; + this.containerParams = fields.containerParams; + } + + static layout(property?: string) { + return borsh.struct( + [ + borsh.option(borsh.vecU8(), "name"), + borsh.option(borsh.vecU8(), "metadata"), + borsh.option(borsh.u64(), "bounty"), + borsh.vecU8("schedule"), + borsh.option(borsh.u32(), "maxContainerParamsLen"), + borsh.vecU8("containerParams"), + ], + property + ); + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + static fromDecoded(obj: any) { + return new FunctionRoutineInitParams({ + name: + (obj.name && + new Uint8Array( + obj.name.buffer, + obj.name.byteOffset, + obj.name.length + )) || + null, + metadata: + (obj.metadata && + new Uint8Array( + obj.metadata.buffer, + obj.metadata.byteOffset, + obj.metadata.length + )) || + null, + bounty: obj.bounty, + schedule: new Uint8Array( + obj.schedule.buffer, + obj.schedule.byteOffset, + obj.schedule.length + ), + maxContainerParamsLen: obj.maxContainerParamsLen, + containerParams: new Uint8Array( + obj.containerParams.buffer, + obj.containerParams.byteOffset, + obj.containerParams.length + ), + }); + } + + static toEncodable(fields: FunctionRoutineInitParamsFields) { + return { + name: + (fields.name && + Buffer.from( + fields.name.buffer, + fields.name.byteOffset, + fields.name.length + )) || + null, + metadata: + (fields.metadata && + Buffer.from( + fields.metadata.buffer, + fields.metadata.byteOffset, + fields.metadata.length + )) || + null, + bounty: fields.bounty, + schedule: Buffer.from( + fields.schedule.buffer, + fields.schedule.byteOffset, + fields.schedule.length + ), + maxContainerParamsLen: fields.maxContainerParamsLen, + containerParams: Buffer.from( + fields.containerParams.buffer, + fields.containerParams.byteOffset, + fields.containerParams.length + ), + }; + } + + toJSON(): FunctionRoutineInitParamsJSON { + return { + name: (this.name && Array.from(this.name.values())) || null, + metadata: (this.metadata && Array.from(this.metadata.values())) || null, + bounty: (this.bounty && this.bounty.toString()) || null, + schedule: Array.from(this.schedule.values()), + maxContainerParamsLen: this.maxContainerParamsLen, + containerParams: Array.from(this.containerParams.values()), + }; + } + + static fromJSON( + obj: FunctionRoutineInitParamsJSON + ): FunctionRoutineInitParams { + return new FunctionRoutineInitParams({ + name: (obj.name && Uint8Array.from(obj.name)) || null, + metadata: (obj.metadata && Uint8Array.from(obj.metadata)) || null, + bounty: (obj.bounty && new BN(obj.bounty)) || null, + schedule: Uint8Array.from(obj.schedule), + maxContainerParamsLen: obj.maxContainerParamsLen, + containerParams: Uint8Array.from(obj.containerParams), + }); + } + + toEncodable() { + return FunctionRoutineInitParams.toEncodable(this); + } +} diff --git a/javascript/solana.js/src/generated/attestation-program/types/FunctionRoutineSetConfigParams.ts b/javascript/solana.js/src/generated/attestation-program/types/FunctionRoutineSetConfigParams.ts new file mode 100644 index 000000000..5c5b483be --- /dev/null +++ b/javascript/solana.js/src/generated/attestation-program/types/FunctionRoutineSetConfigParams.ts @@ -0,0 +1,166 @@ +import { SwitchboardProgram } from "../../../SwitchboardProgram.js"; +import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars + +import * as borsh from "@coral-xyz/borsh"; +import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars +import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars + +export interface FunctionRoutineSetConfigParamsFields { + name: Uint8Array | null; + metadata: Uint8Array | null; + bounty: BN | null; + schedule: Uint8Array | null; + containerParams: Uint8Array | null; + appendContainerParams: boolean; +} + +export interface FunctionRoutineSetConfigParamsJSON { + name: Array | null; + metadata: Array | null; + bounty: string | null; + schedule: Array | null; + containerParams: Array | null; + appendContainerParams: boolean; +} + +export class FunctionRoutineSetConfigParams { + readonly name: Uint8Array | null; + readonly metadata: Uint8Array | null; + readonly bounty: BN | null; + readonly schedule: Uint8Array | null; + readonly containerParams: Uint8Array | null; + readonly appendContainerParams: boolean; + + constructor(fields: FunctionRoutineSetConfigParamsFields) { + this.name = fields.name; + this.metadata = fields.metadata; + this.bounty = fields.bounty; + this.schedule = fields.schedule; + this.containerParams = fields.containerParams; + this.appendContainerParams = fields.appendContainerParams; + } + + static layout(property?: string) { + return borsh.struct( + [ + borsh.option(borsh.vecU8(), "name"), + borsh.option(borsh.vecU8(), "metadata"), + borsh.option(borsh.u64(), "bounty"), + borsh.option(borsh.vecU8(), "schedule"), + borsh.option(borsh.vecU8(), "containerParams"), + borsh.bool("appendContainerParams"), + ], + property + ); + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + static fromDecoded(obj: any) { + return new FunctionRoutineSetConfigParams({ + name: + (obj.name && + new Uint8Array( + obj.name.buffer, + obj.name.byteOffset, + obj.name.length + )) || + null, + metadata: + (obj.metadata && + new Uint8Array( + obj.metadata.buffer, + obj.metadata.byteOffset, + obj.metadata.length + )) || + null, + bounty: obj.bounty, + schedule: + (obj.schedule && + new Uint8Array( + obj.schedule.buffer, + obj.schedule.byteOffset, + obj.schedule.length + )) || + null, + containerParams: + (obj.containerParams && + new Uint8Array( + obj.containerParams.buffer, + obj.containerParams.byteOffset, + obj.containerParams.length + )) || + null, + appendContainerParams: obj.appendContainerParams, + }); + } + + static toEncodable(fields: FunctionRoutineSetConfigParamsFields) { + return { + name: + (fields.name && + Buffer.from( + fields.name.buffer, + fields.name.byteOffset, + fields.name.length + )) || + null, + metadata: + (fields.metadata && + Buffer.from( + fields.metadata.buffer, + fields.metadata.byteOffset, + fields.metadata.length + )) || + null, + bounty: fields.bounty, + schedule: + (fields.schedule && + Buffer.from( + fields.schedule.buffer, + fields.schedule.byteOffset, + fields.schedule.length + )) || + null, + containerParams: + (fields.containerParams && + Buffer.from( + fields.containerParams.buffer, + fields.containerParams.byteOffset, + fields.containerParams.length + )) || + null, + appendContainerParams: fields.appendContainerParams, + }; + } + + toJSON(): FunctionRoutineSetConfigParamsJSON { + return { + name: (this.name && Array.from(this.name.values())) || null, + metadata: (this.metadata && Array.from(this.metadata.values())) || null, + bounty: (this.bounty && this.bounty.toString()) || null, + schedule: (this.schedule && Array.from(this.schedule.values())) || null, + containerParams: + (this.containerParams && Array.from(this.containerParams.values())) || + null, + appendContainerParams: this.appendContainerParams, + }; + } + + static fromJSON( + obj: FunctionRoutineSetConfigParamsJSON + ): FunctionRoutineSetConfigParams { + return new FunctionRoutineSetConfigParams({ + name: (obj.name && Uint8Array.from(obj.name)) || null, + metadata: (obj.metadata && Uint8Array.from(obj.metadata)) || null, + bounty: (obj.bounty && new BN(obj.bounty)) || null, + schedule: (obj.schedule && Uint8Array.from(obj.schedule)) || null, + containerParams: + (obj.containerParams && Uint8Array.from(obj.containerParams)) || null, + appendContainerParams: obj.appendContainerParams, + }); + } + + toEncodable() { + return FunctionRoutineSetConfigParams.toEncodable(this); + } +} diff --git a/javascript/solana.js/src/generated/attestation-program/types/FunctionRoutineVerifyParams.ts b/javascript/solana.js/src/generated/attestation-program/types/FunctionRoutineVerifyParams.ts new file mode 100644 index 000000000..752b04049 --- /dev/null +++ b/javascript/solana.js/src/generated/attestation-program/types/FunctionRoutineVerifyParams.ts @@ -0,0 +1,98 @@ +import { SwitchboardProgram } from "../../../SwitchboardProgram.js"; +import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars + +import * as borsh from "@coral-xyz/borsh"; +import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars +import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars + +export interface FunctionRoutineVerifyParamsFields { + observedTime: BN; + nextAllowedTimestamp: BN; + errorCode: number; + mrEnclave: Array; + containerParamsHash: Array; +} + +export interface FunctionRoutineVerifyParamsJSON { + observedTime: string; + nextAllowedTimestamp: string; + errorCode: number; + mrEnclave: Array; + containerParamsHash: Array; +} + +export class FunctionRoutineVerifyParams { + readonly observedTime: BN; + readonly nextAllowedTimestamp: BN; + readonly errorCode: number; + readonly mrEnclave: Array; + readonly containerParamsHash: Array; + + constructor(fields: FunctionRoutineVerifyParamsFields) { + this.observedTime = fields.observedTime; + this.nextAllowedTimestamp = fields.nextAllowedTimestamp; + this.errorCode = fields.errorCode; + this.mrEnclave = fields.mrEnclave; + this.containerParamsHash = fields.containerParamsHash; + } + + static layout(property?: string) { + return borsh.struct( + [ + borsh.i64("observedTime"), + borsh.i64("nextAllowedTimestamp"), + borsh.u8("errorCode"), + borsh.array(borsh.u8(), 32, "mrEnclave"), + borsh.array(borsh.u8(), 32, "containerParamsHash"), + ], + property + ); + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + static fromDecoded(obj: any) { + return new FunctionRoutineVerifyParams({ + observedTime: obj.observedTime, + nextAllowedTimestamp: obj.nextAllowedTimestamp, + errorCode: obj.errorCode, + mrEnclave: obj.mrEnclave, + containerParamsHash: obj.containerParamsHash, + }); + } + + static toEncodable(fields: FunctionRoutineVerifyParamsFields) { + return { + observedTime: fields.observedTime, + nextAllowedTimestamp: fields.nextAllowedTimestamp, + errorCode: fields.errorCode, + mrEnclave: fields.mrEnclave, + containerParamsHash: fields.containerParamsHash, + }; + } + + toJSON(): FunctionRoutineVerifyParamsJSON { + return { + observedTime: this.observedTime.toString(), + nextAllowedTimestamp: this.nextAllowedTimestamp.toString(), + errorCode: this.errorCode, + mrEnclave: this.mrEnclave, + containerParamsHash: this.containerParamsHash, + }; + } + + static fromJSON( + obj: FunctionRoutineVerifyParamsJSON + ): FunctionRoutineVerifyParams { + return new FunctionRoutineVerifyParams({ + observedTime: new BN(obj.observedTime), + nextAllowedTimestamp: new BN(obj.nextAllowedTimestamp), + errorCode: obj.errorCode, + mrEnclave: obj.mrEnclave, + containerParamsHash: obj.containerParamsHash, + }); + } + + toEncodable() { + return FunctionRoutineVerifyParams.toEncodable(this); + } +} diff --git a/javascript/solana.js/src/generated/attestation-program/types/FunctionSetConfigParams.ts b/javascript/solana.js/src/generated/attestation-program/types/FunctionSetConfigParams.ts index 3b57c567d..5889ed202 100644 --- a/javascript/solana.js/src/generated/attestation-program/types/FunctionSetConfigParams.ts +++ b/javascript/solana.js/src/generated/attestation-program/types/FunctionSetConfigParams.ts @@ -11,11 +11,14 @@ export interface FunctionSetConfigParamsFields { container: Uint8Array | null; containerRegistry: Uint8Array | null; version: Uint8Array | null; - schedule: Uint8Array | null; mrEnclaves: Array> | null; requestsDisabled: boolean | null; requestsRequireAuthorization: boolean | null; - requestsFee: BN | null; + requestsDevFee: BN | null; + routinesDisabled: boolean | null; + lockRoutinesDisabled: boolean | null; + routinesRequireAuthorization: boolean | null; + routinesDevFee: BN | null; } export interface FunctionSetConfigParamsJSON { @@ -24,11 +27,14 @@ export interface FunctionSetConfigParamsJSON { container: Array | null; containerRegistry: Array | null; version: Array | null; - schedule: Array | null; mrEnclaves: Array> | null; requestsDisabled: boolean | null; requestsRequireAuthorization: boolean | null; - requestsFee: string | null; + requestsDevFee: string | null; + routinesDisabled: boolean | null; + lockRoutinesDisabled: boolean | null; + routinesRequireAuthorization: boolean | null; + routinesDevFee: string | null; } export class FunctionSetConfigParams { @@ -37,11 +43,14 @@ export class FunctionSetConfigParams { readonly container: Uint8Array | null; readonly containerRegistry: Uint8Array | null; readonly version: Uint8Array | null; - readonly schedule: Uint8Array | null; readonly mrEnclaves: Array> | null; readonly requestsDisabled: boolean | null; readonly requestsRequireAuthorization: boolean | null; - readonly requestsFee: BN | null; + readonly requestsDevFee: BN | null; + readonly routinesDisabled: boolean | null; + readonly lockRoutinesDisabled: boolean | null; + readonly routinesRequireAuthorization: boolean | null; + readonly routinesDevFee: BN | null; constructor(fields: FunctionSetConfigParamsFields) { this.name = fields.name; @@ -49,11 +58,14 @@ export class FunctionSetConfigParams { this.container = fields.container; this.containerRegistry = fields.containerRegistry; this.version = fields.version; - this.schedule = fields.schedule; this.mrEnclaves = fields.mrEnclaves; this.requestsDisabled = fields.requestsDisabled; this.requestsRequireAuthorization = fields.requestsRequireAuthorization; - this.requestsFee = fields.requestsFee; + this.requestsDevFee = fields.requestsDevFee; + this.routinesDisabled = fields.routinesDisabled; + this.lockRoutinesDisabled = fields.lockRoutinesDisabled; + this.routinesRequireAuthorization = fields.routinesRequireAuthorization; + this.routinesDevFee = fields.routinesDevFee; } static layout(property?: string) { @@ -64,11 +76,14 @@ export class FunctionSetConfigParams { borsh.option(borsh.vecU8(), "container"), borsh.option(borsh.vecU8(), "containerRegistry"), borsh.option(borsh.vecU8(), "version"), - borsh.option(borsh.vecU8(), "schedule"), borsh.option(borsh.vec(borsh.array(borsh.u8(), 32)), "mrEnclaves"), borsh.option(borsh.bool(), "requestsDisabled"), borsh.option(borsh.bool(), "requestsRequireAuthorization"), - borsh.option(borsh.u64(), "requestsFee"), + borsh.option(borsh.u64(), "requestsDevFee"), + borsh.option(borsh.bool(), "routinesDisabled"), + borsh.option(borsh.bool(), "lockRoutinesDisabled"), + borsh.option(borsh.bool(), "routinesRequireAuthorization"), + borsh.option(borsh.u64(), "routinesDevFee"), ], property ); @@ -117,18 +132,14 @@ export class FunctionSetConfigParams { obj.version.length )) || null, - schedule: - (obj.schedule && - new Uint8Array( - obj.schedule.buffer, - obj.schedule.byteOffset, - obj.schedule.length - )) || - null, mrEnclaves: obj.mrEnclaves, requestsDisabled: obj.requestsDisabled, requestsRequireAuthorization: obj.requestsRequireAuthorization, - requestsFee: obj.requestsFee, + requestsDevFee: obj.requestsDevFee, + routinesDisabled: obj.routinesDisabled, + lockRoutinesDisabled: obj.lockRoutinesDisabled, + routinesRequireAuthorization: obj.routinesRequireAuthorization, + routinesDevFee: obj.routinesDevFee, }); } @@ -174,18 +185,14 @@ export class FunctionSetConfigParams { fields.version.length )) || null, - schedule: - (fields.schedule && - Buffer.from( - fields.schedule.buffer, - fields.schedule.byteOffset, - fields.schedule.length - )) || - null, mrEnclaves: fields.mrEnclaves, requestsDisabled: fields.requestsDisabled, requestsRequireAuthorization: fields.requestsRequireAuthorization, - requestsFee: fields.requestsFee, + requestsDevFee: fields.requestsDevFee, + routinesDisabled: fields.routinesDisabled, + lockRoutinesDisabled: fields.lockRoutinesDisabled, + routinesRequireAuthorization: fields.routinesRequireAuthorization, + routinesDevFee: fields.routinesDevFee, }; } @@ -200,11 +207,16 @@ export class FunctionSetConfigParams { Array.from(this.containerRegistry.values())) || null, version: (this.version && Array.from(this.version.values())) || null, - schedule: (this.schedule && Array.from(this.schedule.values())) || null, mrEnclaves: this.mrEnclaves, requestsDisabled: this.requestsDisabled, requestsRequireAuthorization: this.requestsRequireAuthorization, - requestsFee: (this.requestsFee && this.requestsFee.toString()) || null, + requestsDevFee: + (this.requestsDevFee && this.requestsDevFee.toString()) || null, + routinesDisabled: this.routinesDisabled, + lockRoutinesDisabled: this.lockRoutinesDisabled, + routinesRequireAuthorization: this.routinesRequireAuthorization, + routinesDevFee: + (this.routinesDevFee && this.routinesDevFee.toString()) || null, }; } @@ -217,11 +229,16 @@ export class FunctionSetConfigParams { (obj.containerRegistry && Uint8Array.from(obj.containerRegistry)) || null, version: (obj.version && Uint8Array.from(obj.version)) || null, - schedule: (obj.schedule && Uint8Array.from(obj.schedule)) || null, mrEnclaves: obj.mrEnclaves, requestsDisabled: obj.requestsDisabled, requestsRequireAuthorization: obj.requestsRequireAuthorization, - requestsFee: (obj.requestsFee && new BN(obj.requestsFee)) || null, + requestsDevFee: + (obj.requestsDevFee && new BN(obj.requestsDevFee)) || null, + routinesDisabled: obj.routinesDisabled, + lockRoutinesDisabled: obj.lockRoutinesDisabled, + routinesRequireAuthorization: obj.routinesRequireAuthorization, + routinesDevFee: + (obj.routinesDevFee && new BN(obj.routinesDevFee)) || null, }); } diff --git a/javascript/solana.js/src/generated/attestation-program/types/FunctionStatus.ts b/javascript/solana.js/src/generated/attestation-program/types/FunctionStatus.ts index ba6c7f846..d3212f0f1 100644 --- a/javascript/solana.js/src/generated/attestation-program/types/FunctionStatus.ts +++ b/javascript/solana.js/src/generated/attestation-program/types/FunctionStatus.ts @@ -74,25 +74,25 @@ export class NonExecutable { } } -export interface None3JSON { - kind: "None3"; +export interface ErrorKindJSON { + kind: "Error"; } -export class None3 { +export class ErrorKind { static readonly discriminator = 3; - static readonly kind = "None3"; + static readonly kind = "Error"; readonly discriminator = 3; - readonly kind = "None3"; + readonly kind = "Error"; - toJSON(): None3JSON { + toJSON(): ErrorKindJSON { return { - kind: "None3", + kind: "Error", }; } toEncodable() { return { - None3: {}, + Error: {}, }; } } @@ -411,8 +411,8 @@ export function fromDecoded(obj: any): types.FunctionStatusKind { if ("NonExecutable" in obj) { return new NonExecutable(); } - if ("None3" in obj) { - return new None3(); + if ("Error" in obj) { + return new ErrorKind(); } if ("Expired" in obj) { return new Expired(); @@ -470,8 +470,8 @@ export function fromJSON( case "NonExecutable": { return new NonExecutable(); } - case "None3": { - return new None3(); + case "Error": { + return new ErrorKind(); } case "Expired": { return new Expired(); @@ -520,7 +520,7 @@ export function layout(property?: string) { borsh.struct([], "None"), borsh.struct([], "Active"), borsh.struct([], "NonExecutable"), - borsh.struct([], "None3"), + borsh.struct([], "Error"), borsh.struct([], "Expired"), borsh.struct([], "None5"), borsh.struct([], "None6"), diff --git a/javascript/solana.js/src/generated/attestation-program/types/FunctionVerifyParams.ts b/javascript/solana.js/src/generated/attestation-program/types/FunctionVerifyParams.ts index e7d30ddc7..98883f2bd 100644 --- a/javascript/solana.js/src/generated/attestation-program/types/FunctionVerifyParams.ts +++ b/javascript/solana.js/src/generated/attestation-program/types/FunctionVerifyParams.ts @@ -8,27 +8,27 @@ import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript export interface FunctionVerifyParamsFields { observedTime: BN; nextAllowedTimestamp: BN; - isFailure: boolean; + errorCode: number; mrEnclave: Array; } export interface FunctionVerifyParamsJSON { observedTime: string; nextAllowedTimestamp: string; - isFailure: boolean; + errorCode: number; mrEnclave: Array; } export class FunctionVerifyParams { readonly observedTime: BN; readonly nextAllowedTimestamp: BN; - readonly isFailure: boolean; + readonly errorCode: number; readonly mrEnclave: Array; constructor(fields: FunctionVerifyParamsFields) { this.observedTime = fields.observedTime; this.nextAllowedTimestamp = fields.nextAllowedTimestamp; - this.isFailure = fields.isFailure; + this.errorCode = fields.errorCode; this.mrEnclave = fields.mrEnclave; } @@ -37,7 +37,7 @@ export class FunctionVerifyParams { [ borsh.i64("observedTime"), borsh.i64("nextAllowedTimestamp"), - borsh.bool("isFailure"), + borsh.u8("errorCode"), borsh.array(borsh.u8(), 32, "mrEnclave"), ], property @@ -49,7 +49,7 @@ export class FunctionVerifyParams { return new FunctionVerifyParams({ observedTime: obj.observedTime, nextAllowedTimestamp: obj.nextAllowedTimestamp, - isFailure: obj.isFailure, + errorCode: obj.errorCode, mrEnclave: obj.mrEnclave, }); } @@ -58,7 +58,7 @@ export class FunctionVerifyParams { return { observedTime: fields.observedTime, nextAllowedTimestamp: fields.nextAllowedTimestamp, - isFailure: fields.isFailure, + errorCode: fields.errorCode, mrEnclave: fields.mrEnclave, }; } @@ -67,7 +67,7 @@ export class FunctionVerifyParams { return { observedTime: this.observedTime.toString(), nextAllowedTimestamp: this.nextAllowedTimestamp.toString(), - isFailure: this.isFailure, + errorCode: this.errorCode, mrEnclave: this.mrEnclave, }; } @@ -76,7 +76,7 @@ export class FunctionVerifyParams { return new FunctionVerifyParams({ observedTime: new BN(obj.observedTime), nextAllowedTimestamp: new BN(obj.nextAllowedTimestamp), - isFailure: obj.isFailure, + errorCode: obj.errorCode, mrEnclave: obj.mrEnclave, }); } diff --git a/javascript/solana.js/src/generated/attestation-program/types/ResourceLevel.ts b/javascript/solana.js/src/generated/attestation-program/types/ResourceLevel.ts new file mode 100644 index 000000000..6ee3f7623 --- /dev/null +++ b/javascript/solana.js/src/generated/attestation-program/types/ResourceLevel.ts @@ -0,0 +1,152 @@ +import { SwitchboardProgram } from "../../../SwitchboardProgram.js"; +import type * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars + +import * as borsh from "@coral-xyz/borsh"; +import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars +import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars + +export interface NoneJSON { + kind: "None"; +} + +export class None { + static readonly discriminator = 0; + static readonly kind = "None"; + readonly discriminator = 0; + readonly kind = "None"; + + toJSON(): NoneJSON { + return { + kind: "None", + }; + } + + toEncodable() { + return { + None: {}, + }; + } +} + +export interface AuthorityJSON { + kind: "Authority"; +} + +export class Authority { + static readonly discriminator = 1; + static readonly kind = "Authority"; + readonly discriminator = 1; + readonly kind = "Authority"; + + toJSON(): AuthorityJSON { + return { + kind: "Authority", + }; + } + + toEncodable() { + return { + Authority: {}, + }; + } +} + +export interface FunctionJSON { + kind: "Function"; +} + +export class Function { + static readonly discriminator = 2; + static readonly kind = "Function"; + readonly discriminator = 2; + readonly kind = "Function"; + + toJSON(): FunctionJSON { + return { + kind: "Function", + }; + } + + toEncodable() { + return { + Function: {}, + }; + } +} + +export interface QueueJSON { + kind: "Queue"; +} + +export class Queue { + static readonly discriminator = 3; + static readonly kind = "Queue"; + readonly discriminator = 3; + readonly kind = "Queue"; + + toJSON(): QueueJSON { + return { + kind: "Queue", + }; + } + + toEncodable() { + return { + Queue: {}, + }; + } +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function fromDecoded(obj: any): types.ResourceLevelKind { + if (typeof obj !== "object") { + throw new Error("Invalid enum object"); + } + + if ("None" in obj) { + return new None(); + } + if ("Authority" in obj) { + return new Authority(); + } + if ("Function" in obj) { + return new Function(); + } + if ("Queue" in obj) { + return new Queue(); + } + + throw new Error("Invalid enum object"); +} + +export function fromJSON( + obj: types.ResourceLevelJSON +): types.ResourceLevelKind { + switch (obj.kind) { + case "None": { + return new None(); + } + case "Authority": { + return new Authority(); + } + case "Function": { + return new Function(); + } + case "Queue": { + return new Queue(); + } + } +} + +export function layout(property?: string) { + const ret = borsh.rustEnum([ + borsh.struct([], "None"), + borsh.struct([], "Authority"), + borsh.struct([], "Function"), + borsh.struct([], "Queue"), + ]); + if (property !== undefined) { + return ret.replicate(property); + } + return ret; +} diff --git a/javascript/solana.js/src/generated/attestation-program/types/RoutineStatus.ts b/javascript/solana.js/src/generated/attestation-program/types/RoutineStatus.ts new file mode 100644 index 000000000..4f31fa695 --- /dev/null +++ b/javascript/solana.js/src/generated/attestation-program/types/RoutineStatus.ts @@ -0,0 +1,122 @@ +import { SwitchboardProgram } from "../../../SwitchboardProgram.js"; +import type * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars + +import * as borsh from "@coral-xyz/borsh"; +import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars +import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars + +export interface NoneJSON { + kind: "None"; +} + +export class None { + static readonly discriminator = 0; + static readonly kind = "None"; + readonly discriminator = 0; + readonly kind = "None"; + + toJSON(): NoneJSON { + return { + kind: "None", + }; + } + + toEncodable() { + return { + None: {}, + }; + } +} + +export interface ActiveJSON { + kind: "Active"; +} + +export class Active { + static readonly discriminator = 1; + static readonly kind = "Active"; + readonly discriminator = 1; + readonly kind = "Active"; + + toJSON(): ActiveJSON { + return { + kind: "Active", + }; + } + + toEncodable() { + return { + Active: {}, + }; + } +} + +export interface NonExecutableJSON { + kind: "NonExecutable"; +} + +export class NonExecutable { + static readonly discriminator = 2; + static readonly kind = "NonExecutable"; + readonly discriminator = 2; + readonly kind = "NonExecutable"; + + toJSON(): NonExecutableJSON { + return { + kind: "NonExecutable", + }; + } + + toEncodable() { + return { + NonExecutable: {}, + }; + } +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function fromDecoded(obj: any): types.RoutineStatusKind { + if (typeof obj !== "object") { + throw new Error("Invalid enum object"); + } + + if ("None" in obj) { + return new None(); + } + if ("Active" in obj) { + return new Active(); + } + if ("NonExecutable" in obj) { + return new NonExecutable(); + } + + throw new Error("Invalid enum object"); +} + +export function fromJSON( + obj: types.RoutineStatusJSON +): types.RoutineStatusKind { + switch (obj.kind) { + case "None": { + return new None(); + } + case "Active": { + return new Active(); + } + case "NonExecutable": { + return new NonExecutable(); + } + } +} + +export function layout(property?: string) { + const ret = borsh.rustEnum([ + borsh.struct([], "None"), + borsh.struct([], "Active"), + borsh.struct([], "NonExecutable"), + ]); + if (property !== undefined) { + return ret.replicate(property); + } + return ret; +} diff --git a/javascript/solana.js/src/generated/attestation-program/types/WalletInitParams.ts b/javascript/solana.js/src/generated/attestation-program/types/WalletInitParams.ts index dbaf4623a..fe2663249 100644 --- a/javascript/solana.js/src/generated/attestation-program/types/WalletInitParams.ts +++ b/javascript/solana.js/src/generated/attestation-program/types/WalletInitParams.ts @@ -7,28 +7,21 @@ import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript export interface WalletInitParamsFields { name: Uint8Array; - maxLen: number | null; } export interface WalletInitParamsJSON { name: Array; - maxLen: number | null; } export class WalletInitParams { readonly name: Uint8Array; - readonly maxLen: number | null; constructor(fields: WalletInitParamsFields) { this.name = fields.name; - this.maxLen = fields.maxLen; } static layout(property?: string) { - return borsh.struct( - [borsh.vecU8("name"), borsh.option(borsh.u32(), "maxLen")], - property - ); + return borsh.struct([borsh.vecU8("name")], property); } // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -39,7 +32,6 @@ export class WalletInitParams { obj.name.byteOffset, obj.name.length ), - maxLen: obj.maxLen, }); } @@ -50,21 +42,18 @@ export class WalletInitParams { fields.name.byteOffset, fields.name.length ), - maxLen: fields.maxLen, }; } toJSON(): WalletInitParamsJSON { return { name: Array.from(this.name.values()), - maxLen: this.maxLen, }; } static fromJSON(obj: WalletInitParamsJSON): WalletInitParams { return new WalletInitParams({ name: Uint8Array.from(obj.name), - maxLen: obj.maxLen, }); } diff --git a/javascript/solana.js/src/generated/attestation-program/types/index.ts b/javascript/solana.js/src/generated/attestation-program/types/index.ts index da3260695..3f0f19d23 100644 --- a/javascript/solana.js/src/generated/attestation-program/types/index.ts +++ b/javascript/solana.js/src/generated/attestation-program/types/index.ts @@ -1,6 +1,9 @@ +import * as BoolWithLock from "./BoolWithLock.js"; import * as FunctionStatus from "./FunctionStatus.js"; import * as FundingStatus from "./FundingStatus.js"; import * as RequestStatus from "./RequestStatus.js"; +import * as ResourceLevel from "./ResourceLevel.js"; +import * as RoutineStatus from "./RoutineStatus.js"; import * as SwitchboardAttestationPermission from "./SwitchboardAttestationPermission.js"; import * as VerificationStatus from "./VerificationStatus.js"; @@ -84,6 +87,26 @@ export type { FunctionResetEscrowParamsJSON, } from "./FunctionResetEscrowParams.js"; export { FunctionResetEscrowParams } from "./FunctionResetEscrowParams.js"; +export type { + FunctionRoutineDisableParamsFields, + FunctionRoutineDisableParamsJSON, +} from "./FunctionRoutineDisableParams.js"; +export { FunctionRoutineDisableParams } from "./FunctionRoutineDisableParams.js"; +export type { + FunctionRoutineInitParamsFields, + FunctionRoutineInitParamsJSON, +} from "./FunctionRoutineInitParams.js"; +export { FunctionRoutineInitParams } from "./FunctionRoutineInitParams.js"; +export type { + FunctionRoutineSetConfigParamsFields, + FunctionRoutineSetConfigParamsJSON, +} from "./FunctionRoutineSetConfigParams.js"; +export { FunctionRoutineSetConfigParams } from "./FunctionRoutineSetConfigParams.js"; +export type { + FunctionRoutineVerifyParamsFields, + FunctionRoutineVerifyParamsJSON, +} from "./FunctionRoutineVerifyParams.js"; +export { FunctionRoutineVerifyParams } from "./FunctionRoutineVerifyParams.js"; export type { FunctionSetAuthorityParamsFields, FunctionSetAuthorityParamsJSON, @@ -156,13 +179,56 @@ export type { WalletWithdrawParamsJSON, } from "./WalletWithdrawParams.js"; export { WalletWithdrawParams } from "./WalletWithdrawParams.js"; +export { BoolWithLock }; + +/** + * An enum representing a boolean flag which can be locked. + * Byte #0: 0 = Disabled, 1 = Enabled + * Byte #1: 0 = Unlocked, 1 = Locked + */ +export type BoolWithLockKind = + | BoolWithLock.Disabled + | BoolWithLock.Enabled + | BoolWithLock.DisabledLocked + | BoolWithLock.EnabledLocked; +export type BoolWithLockJSON = + | BoolWithLock.DisabledJSON + | BoolWithLock.EnabledJSON + | BoolWithLock.DisabledLockedJSON + | BoolWithLock.EnabledLockedJSON; + +export { ResourceLevel }; + +/** An enum representing a heirarchy of resources that can modify a field. */ +export type ResourceLevelKind = + | ResourceLevel.None + | ResourceLevel.Authority + | ResourceLevel.Function + | ResourceLevel.Queue; +export type ResourceLevelJSON = + | ResourceLevel.NoneJSON + | ResourceLevel.AuthorityJSON + | ResourceLevel.FunctionJSON + | ResourceLevel.QueueJSON; + +export { RoutineStatus }; + +export type RoutineStatusKind = + | RoutineStatus.None + | RoutineStatus.Active + | RoutineStatus.NonExecutable; +export type RoutineStatusJSON = + | RoutineStatus.NoneJSON + | RoutineStatus.ActiveJSON + | RoutineStatus.NonExecutableJSON; + export { FunctionStatus }; export type FunctionStatusKind = | FunctionStatus.None | FunctionStatus.Active | FunctionStatus.NonExecutable - | FunctionStatus.None3 + | FunctionStatus.ErrorKind | FunctionStatus.Expired | FunctionStatus.None5 | FunctionStatus.None6 @@ -180,7 +246,7 @@ export type FunctionStatusJSON = | FunctionStatus.NoneJSON | FunctionStatus.ActiveJSON | FunctionStatus.NonExecutableJSON - | FunctionStatus.None3JSON + | FunctionStatus.ErrorKindJSON | FunctionStatus.ExpiredJSON | FunctionStatus.None5JSON | FunctionStatus.None6JSON diff --git a/javascript/solana.js/src/generated/oracle-program/accounts/AggregatorAccountData.ts b/javascript/solana.js/src/generated/oracle-program/accounts/AggregatorAccountData.ts index 82154fca0..2c79484ce 100644 --- a/javascript/solana.js/src/generated/oracle-program/accounts/AggregatorAccountData.ts +++ b/javascript/solana.js/src/generated/oracle-program/accounts/AggregatorAccountData.ts @@ -320,7 +320,7 @@ export class AggregatorAccountData { static async fetch( program: SwitchboardProgram, address: PublicKey, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise { const info = await program.connection.getAccountInfo(address); @@ -337,7 +337,7 @@ export class AggregatorAccountData { static async fetchMultiple( program: SwitchboardProgram, addresses: PublicKey[], - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise> { const infos = await program.connection.getMultipleAccountsInfo(addresses); diff --git a/javascript/solana.js/src/generated/oracle-program/accounts/BufferRelayerAccountData.ts b/javascript/solana.js/src/generated/oracle-program/accounts/BufferRelayerAccountData.ts index 6a738548d..3a0ac9234 100644 --- a/javascript/solana.js/src/generated/oracle-program/accounts/BufferRelayerAccountData.ts +++ b/javascript/solana.js/src/generated/oracle-program/accounts/BufferRelayerAccountData.ts @@ -118,7 +118,7 @@ export class BufferRelayerAccountData { static async fetch( program: SwitchboardProgram, address: PublicKey, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise { const info = await program.connection.getAccountInfo(address); @@ -135,7 +135,7 @@ export class BufferRelayerAccountData { static async fetchMultiple( program: SwitchboardProgram, addresses: PublicKey[], - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise> { const infos = await program.connection.getMultipleAccountsInfo(addresses); diff --git a/javascript/solana.js/src/generated/oracle-program/accounts/CrankAccountData.ts b/javascript/solana.js/src/generated/oracle-program/accounts/CrankAccountData.ts index f2c89c972..4982cd945 100644 --- a/javascript/solana.js/src/generated/oracle-program/accounts/CrankAccountData.ts +++ b/javascript/solana.js/src/generated/oracle-program/accounts/CrankAccountData.ts @@ -90,7 +90,7 @@ export class CrankAccountData { static async fetch( program: SwitchboardProgram, address: PublicKey, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise { const info = await program.connection.getAccountInfo(address); @@ -107,7 +107,7 @@ export class CrankAccountData { static async fetchMultiple( program: SwitchboardProgram, addresses: PublicKey[], - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise> { const infos = await program.connection.getMultipleAccountsInfo(addresses); diff --git a/javascript/solana.js/src/generated/oracle-program/accounts/JobAccountData.ts b/javascript/solana.js/src/generated/oracle-program/accounts/JobAccountData.ts index b775e2410..db62acb19 100644 --- a/javascript/solana.js/src/generated/oracle-program/accounts/JobAccountData.ts +++ b/javascript/solana.js/src/generated/oracle-program/accounts/JobAccountData.ts @@ -103,7 +103,7 @@ export class JobAccountData { static async fetch( program: SwitchboardProgram, address: PublicKey, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise { const info = await program.connection.getAccountInfo(address); @@ -120,7 +120,7 @@ export class JobAccountData { static async fetchMultiple( program: SwitchboardProgram, addresses: PublicKey[], - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise> { const infos = await program.connection.getMultipleAccountsInfo(addresses); diff --git a/javascript/solana.js/src/generated/oracle-program/accounts/LeaseAccountData.ts b/javascript/solana.js/src/generated/oracle-program/accounts/LeaseAccountData.ts index c37cda32c..70bd61c82 100644 --- a/javascript/solana.js/src/generated/oracle-program/accounts/LeaseAccountData.ts +++ b/javascript/solana.js/src/generated/oracle-program/accounts/LeaseAccountData.ts @@ -112,7 +112,7 @@ export class LeaseAccountData { static async fetch( program: SwitchboardProgram, address: PublicKey, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise { const info = await program.connection.getAccountInfo(address); @@ -129,7 +129,7 @@ export class LeaseAccountData { static async fetchMultiple( program: SwitchboardProgram, addresses: PublicKey[], - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise> { const infos = await program.connection.getMultipleAccountsInfo(addresses); diff --git a/javascript/solana.js/src/generated/oracle-program/accounts/OracleAccountData.ts b/javascript/solana.js/src/generated/oracle-program/accounts/OracleAccountData.ts index ee63282f0..5c790d864 100644 --- a/javascript/solana.js/src/generated/oracle-program/accounts/OracleAccountData.ts +++ b/javascript/solana.js/src/generated/oracle-program/accounts/OracleAccountData.ts @@ -106,7 +106,7 @@ export class OracleAccountData { static async fetch( program: SwitchboardProgram, address: PublicKey, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise { const info = await program.connection.getAccountInfo(address); @@ -123,7 +123,7 @@ export class OracleAccountData { static async fetchMultiple( program: SwitchboardProgram, addresses: PublicKey[], - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise> { const infos = await program.connection.getMultipleAccountsInfo(addresses); diff --git a/javascript/solana.js/src/generated/oracle-program/accounts/OracleQueueAccountData.ts b/javascript/solana.js/src/generated/oracle-program/accounts/OracleQueueAccountData.ts index af618bd46..9a1723450 100644 --- a/javascript/solana.js/src/generated/oracle-program/accounts/OracleQueueAccountData.ts +++ b/javascript/solana.js/src/generated/oracle-program/accounts/OracleQueueAccountData.ts @@ -246,7 +246,7 @@ export class OracleQueueAccountData { static async fetch( program: SwitchboardProgram, address: PublicKey, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise { const info = await program.connection.getAccountInfo(address); @@ -263,7 +263,7 @@ export class OracleQueueAccountData { static async fetchMultiple( program: SwitchboardProgram, addresses: PublicKey[], - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise> { const infos = await program.connection.getMultipleAccountsInfo(addresses); diff --git a/javascript/solana.js/src/generated/oracle-program/accounts/PermissionAccountData.ts b/javascript/solana.js/src/generated/oracle-program/accounts/PermissionAccountData.ts index 361374dee..8a7bd3470 100644 --- a/javascript/solana.js/src/generated/oracle-program/accounts/PermissionAccountData.ts +++ b/javascript/solana.js/src/generated/oracle-program/accounts/PermissionAccountData.ts @@ -94,7 +94,7 @@ export class PermissionAccountData { static async fetch( program: SwitchboardProgram, address: PublicKey, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise { const info = await program.connection.getAccountInfo(address); @@ -111,7 +111,7 @@ export class PermissionAccountData { static async fetchMultiple( program: SwitchboardProgram, addresses: PublicKey[], - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise> { const infos = await program.connection.getMultipleAccountsInfo(addresses); diff --git a/javascript/solana.js/src/generated/oracle-program/accounts/RealmSpawnRecordAccountData.ts b/javascript/solana.js/src/generated/oracle-program/accounts/RealmSpawnRecordAccountData.ts index 61893bca7..58b247170 100644 --- a/javascript/solana.js/src/generated/oracle-program/accounts/RealmSpawnRecordAccountData.ts +++ b/javascript/solana.js/src/generated/oracle-program/accounts/RealmSpawnRecordAccountData.ts @@ -30,7 +30,7 @@ export class RealmSpawnRecordAccountData { static async fetch( program: SwitchboardProgram, address: PublicKey, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise { const info = await program.connection.getAccountInfo(address); @@ -47,7 +47,7 @@ export class RealmSpawnRecordAccountData { static async fetchMultiple( program: SwitchboardProgram, addresses: PublicKey[], - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise> { const infos = await program.connection.getMultipleAccountsInfo(addresses); diff --git a/javascript/solana.js/src/generated/oracle-program/accounts/SbState.ts b/javascript/solana.js/src/generated/oracle-program/accounts/SbState.ts index 2ba953a9d..2f6450bc7 100644 --- a/javascript/solana.js/src/generated/oracle-program/accounts/SbState.ts +++ b/javascript/solana.js/src/generated/oracle-program/accounts/SbState.ts @@ -82,7 +82,7 @@ export class SbState { static async fetch( program: SwitchboardProgram, address: PublicKey, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise { const info = await program.connection.getAccountInfo(address); @@ -99,7 +99,7 @@ export class SbState { static async fetchMultiple( program: SwitchboardProgram, addresses: PublicKey[], - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise> { const infos = await program.connection.getMultipleAccountsInfo(addresses); diff --git a/javascript/solana.js/src/generated/oracle-program/accounts/SlidingResultAccountData.ts b/javascript/solana.js/src/generated/oracle-program/accounts/SlidingResultAccountData.ts index cebe00d1c..b1a394de7 100644 --- a/javascript/solana.js/src/generated/oracle-program/accounts/SlidingResultAccountData.ts +++ b/javascript/solana.js/src/generated/oracle-program/accounts/SlidingResultAccountData.ts @@ -44,7 +44,7 @@ export class SlidingResultAccountData { static async fetch( program: SwitchboardProgram, address: PublicKey, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise { const info = await program.connection.getAccountInfo(address); @@ -61,7 +61,7 @@ export class SlidingResultAccountData { static async fetchMultiple( program: SwitchboardProgram, addresses: PublicKey[], - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise> { const infos = await program.connection.getMultipleAccountsInfo(addresses); diff --git a/javascript/solana.js/src/generated/oracle-program/accounts/TaskSpecRecord.ts b/javascript/solana.js/src/generated/oracle-program/accounts/TaskSpecRecord.ts index bf2293b17..edc733fd8 100644 --- a/javascript/solana.js/src/generated/oracle-program/accounts/TaskSpecRecord.ts +++ b/javascript/solana.js/src/generated/oracle-program/accounts/TaskSpecRecord.ts @@ -30,7 +30,7 @@ export class TaskSpecRecord { static async fetch( program: SwitchboardProgram, address: PublicKey, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise { const info = await program.connection.getAccountInfo(address); @@ -47,7 +47,7 @@ export class TaskSpecRecord { static async fetchMultiple( program: SwitchboardProgram, addresses: PublicKey[], - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise> { const infos = await program.connection.getMultipleAccountsInfo(addresses); diff --git a/javascript/solana.js/src/generated/oracle-program/accounts/VrfAccountData.ts b/javascript/solana.js/src/generated/oracle-program/accounts/VrfAccountData.ts index 004c43685..e0590fc8f 100644 --- a/javascript/solana.js/src/generated/oracle-program/accounts/VrfAccountData.ts +++ b/javascript/solana.js/src/generated/oracle-program/accounts/VrfAccountData.ts @@ -121,7 +121,7 @@ export class VrfAccountData { static async fetch( program: SwitchboardProgram, address: PublicKey, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise { const info = await program.connection.getAccountInfo(address); @@ -138,7 +138,7 @@ export class VrfAccountData { static async fetchMultiple( program: SwitchboardProgram, addresses: PublicKey[], - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise> { const infos = await program.connection.getMultipleAccountsInfo(addresses); diff --git a/javascript/solana.js/src/generated/oracle-program/accounts/VrfLiteAccountData.ts b/javascript/solana.js/src/generated/oracle-program/accounts/VrfLiteAccountData.ts index fbd2b5f10..2cc06ed04 100644 --- a/javascript/solana.js/src/generated/oracle-program/accounts/VrfLiteAccountData.ts +++ b/javascript/solana.js/src/generated/oracle-program/accounts/VrfLiteAccountData.ts @@ -156,7 +156,7 @@ export class VrfLiteAccountData { static async fetch( program: SwitchboardProgram, address: PublicKey, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise { const info = await program.connection.getAccountInfo(address); @@ -173,7 +173,7 @@ export class VrfLiteAccountData { static async fetchMultiple( program: SwitchboardProgram, addresses: PublicKey[], - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise> { const infos = await program.connection.getMultipleAccountsInfo(addresses); diff --git a/javascript/solana.js/src/generated/oracle-program/accounts/VrfPoolAccountData.ts b/javascript/solana.js/src/generated/oracle-program/accounts/VrfPoolAccountData.ts index 5cb54bd50..073fff6f0 100644 --- a/javascript/solana.js/src/generated/oracle-program/accounts/VrfPoolAccountData.ts +++ b/javascript/solana.js/src/generated/oracle-program/accounts/VrfPoolAccountData.ts @@ -74,7 +74,7 @@ export class VrfPoolAccountData { static async fetch( program: SwitchboardProgram, address: PublicKey, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise { const info = await program.connection.getAccountInfo(address); @@ -91,7 +91,7 @@ export class VrfPoolAccountData { static async fetchMultiple( program: SwitchboardProgram, addresses: PublicKey[], - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ): Promise> { const infos = await program.connection.getMultipleAccountsInfo(addresses); diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorAddJob.ts b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorAddJob.ts index 72cbaa567..f848050b6 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorAddJob.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorAddJob.ts @@ -24,7 +24,7 @@ export function aggregatorAddJob( program: SwitchboardProgram, args: AggregatorAddJobArgs, accounts: AggregatorAddJobAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.aggregator, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorClose.ts b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorClose.ts index d0b1a024f..9c7bde3e9 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorClose.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorClose.ts @@ -36,7 +36,7 @@ export function aggregatorClose( program: SwitchboardProgram, args: AggregatorCloseArgs, accounts: AggregatorCloseAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.authority, isSigner: true, isWritable: false }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorInit.ts b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorInit.ts index 9090506c8..b5c356b7c 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorInit.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorInit.ts @@ -25,7 +25,7 @@ export function aggregatorInit( program: SwitchboardProgram, args: AggregatorInitArgs, accounts: AggregatorInitAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.aggregator, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorLock.ts b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorLock.ts index 60e65e547..2031c82f2 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorLock.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorLock.ts @@ -23,7 +23,7 @@ export function aggregatorLock( program: SwitchboardProgram, args: AggregatorLockArgs, accounts: AggregatorLockAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.aggregator, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorOpenRound.ts b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorOpenRound.ts index f171b5d14..fdab68cff 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorOpenRound.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorOpenRound.ts @@ -32,7 +32,7 @@ export function aggregatorOpenRound( program: SwitchboardProgram, args: AggregatorOpenRoundArgs, accounts: AggregatorOpenRoundAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.aggregator, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorRemoveJob.ts b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorRemoveJob.ts index 41b7453c3..9e4fc5af4 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorRemoveJob.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorRemoveJob.ts @@ -24,7 +24,7 @@ export function aggregatorRemoveJob( program: SwitchboardProgram, args: AggregatorRemoveJobArgs, accounts: AggregatorRemoveJobAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.aggregator, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSaveResult.ts b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSaveResult.ts index e500d8758..c2948a1eb 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSaveResult.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSaveResult.ts @@ -34,7 +34,7 @@ export function aggregatorSaveResult( program: SwitchboardProgram, args: AggregatorSaveResultArgs, accounts: AggregatorSaveResultAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.aggregator, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSaveResultV2.ts b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSaveResultV2.ts index 8bb3b390d..4e1d989ba 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSaveResultV2.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSaveResultV2.ts @@ -34,7 +34,7 @@ export function aggregatorSaveResultV2( program: SwitchboardProgram, args: AggregatorSaveResultV2Args, accounts: AggregatorSaveResultV2Accounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.aggregator, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetAuthority.ts b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetAuthority.ts index 24977404d..efa056fba 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetAuthority.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetAuthority.ts @@ -24,7 +24,7 @@ export function aggregatorSetAuthority( program: SwitchboardProgram, args: AggregatorSetAuthorityArgs, accounts: AggregatorSetAuthorityAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.aggregator, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetConfig.ts b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetConfig.ts index 38f57f0e5..5978efd7c 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetConfig.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetConfig.ts @@ -23,7 +23,7 @@ export function aggregatorSetConfig( program: SwitchboardProgram, args: AggregatorSetConfigArgs, accounts: AggregatorSetConfigAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.aggregator, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetHistoryBuffer.ts b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetHistoryBuffer.ts index 7d5317cf2..41a393137 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetHistoryBuffer.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetHistoryBuffer.ts @@ -24,7 +24,7 @@ export function aggregatorSetHistoryBuffer( program: SwitchboardProgram, args: AggregatorSetHistoryBufferArgs, accounts: AggregatorSetHistoryBufferAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.aggregator, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetQueue.ts b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetQueue.ts index 01c6b5609..27cd7067d 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetQueue.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetQueue.ts @@ -24,7 +24,7 @@ export function aggregatorSetQueue( program: SwitchboardProgram, args: AggregatorSetQueueArgs, accounts: AggregatorSetQueueAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.aggregator, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetResolutionMode.ts b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetResolutionMode.ts index db49be208..c2783fd24 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetResolutionMode.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorSetResolutionMode.ts @@ -26,7 +26,7 @@ export function aggregatorSetResolutionMode( program: SwitchboardProgram, args: AggregatorSetResolutionModeArgs, accounts: AggregatorSetResolutionModeAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.aggregator, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorTeeSaveResult.ts b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorTeeSaveResult.ts index 882edd891..451508024 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorTeeSaveResult.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/aggregatorTeeSaveResult.ts @@ -39,7 +39,7 @@ export function aggregatorTeeSaveResult( program: SwitchboardProgram, args: AggregatorTeeSaveResultArgs, accounts: AggregatorTeeSaveResultAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.aggregator, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/bufferRelayerInit.ts b/javascript/solana.js/src/generated/oracle-program/instructions/bufferRelayerInit.ts index 30e20c1fd..c95354711 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/bufferRelayerInit.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/bufferRelayerInit.ts @@ -33,7 +33,7 @@ export function bufferRelayerInit( program: SwitchboardProgram, args: BufferRelayerInitArgs, accounts: BufferRelayerInitAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.bufferRelayer, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/bufferRelayerOpenRound.ts b/javascript/solana.js/src/generated/oracle-program/instructions/bufferRelayerOpenRound.ts index e8d7e918e..f8e7ab761 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/bufferRelayerOpenRound.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/bufferRelayerOpenRound.ts @@ -27,7 +27,7 @@ export function bufferRelayerOpenRound( program: SwitchboardProgram, args: BufferRelayerOpenRoundArgs, accounts: BufferRelayerOpenRoundAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.bufferRelayer, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/bufferRelayerSaveResult.ts b/javascript/solana.js/src/generated/oracle-program/instructions/bufferRelayerSaveResult.ts index 51d1bccba..1e5566b90 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/bufferRelayerSaveResult.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/bufferRelayerSaveResult.ts @@ -32,7 +32,7 @@ export function bufferRelayerSaveResult( program: SwitchboardProgram, args: BufferRelayerSaveResultArgs, accounts: BufferRelayerSaveResultAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.bufferRelayer, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/crankInit.ts b/javascript/solana.js/src/generated/oracle-program/instructions/crankInit.ts index dfc87cd74..a8e1cc91e 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/crankInit.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/crankInit.ts @@ -24,7 +24,7 @@ export function crankInit( program: SwitchboardProgram, args: CrankInitArgs, accounts: CrankInitAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.crank, isSigner: true, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/crankPop.ts b/javascript/solana.js/src/generated/oracle-program/instructions/crankPop.ts index d8d50c565..2766ebb0d 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/crankPop.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/crankPop.ts @@ -28,7 +28,7 @@ export function crankPop( program: SwitchboardProgram, args: CrankPopArgs, accounts: CrankPopAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.crank, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/crankPopV2.ts b/javascript/solana.js/src/generated/oracle-program/instructions/crankPopV2.ts index 6064cc3d9..d0cdda22c 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/crankPopV2.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/crankPopV2.ts @@ -28,7 +28,7 @@ export function crankPopV2( program: SwitchboardProgram, args: CrankPopV2Args, accounts: CrankPopV2Accounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.crank, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/crankPush.ts b/javascript/solana.js/src/generated/oracle-program/instructions/crankPush.ts index f04d1aa1f..98a36201a 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/crankPush.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/crankPush.ts @@ -28,7 +28,7 @@ export function crankPush( program: SwitchboardProgram, args: CrankPushArgs, accounts: CrankPushAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.crank, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/jobInit.ts b/javascript/solana.js/src/generated/oracle-program/instructions/jobInit.ts index 120d3452d..ce735e672 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/jobInit.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/jobInit.ts @@ -24,7 +24,7 @@ export function jobInit( program: SwitchboardProgram, args: JobInitArgs, accounts: JobInitAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.job, isSigner: true, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/jobSetData.ts b/javascript/solana.js/src/generated/oracle-program/instructions/jobSetData.ts index bce990e9f..cb4f1ada9 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/jobSetData.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/jobSetData.ts @@ -21,7 +21,7 @@ export function jobSetData( program: SwitchboardProgram, args: JobSetDataArgs, accounts: JobSetDataAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.job, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/leaseExtend.ts b/javascript/solana.js/src/generated/oracle-program/instructions/leaseExtend.ts index 785610f6f..9c8502018 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/leaseExtend.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/leaseExtend.ts @@ -28,7 +28,7 @@ export function leaseExtend( program: SwitchboardProgram, args: LeaseExtendArgs, accounts: LeaseExtendAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.lease, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/leaseInit.ts b/javascript/solana.js/src/generated/oracle-program/instructions/leaseInit.ts index 507cdca1e..e81622957 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/leaseInit.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/leaseInit.ts @@ -30,7 +30,7 @@ export function leaseInit( program: SwitchboardProgram, args: LeaseInitArgs, accounts: LeaseInitAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.lease, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/leaseSetAuthority.ts b/javascript/solana.js/src/generated/oracle-program/instructions/leaseSetAuthority.ts index cd3d363c2..6ac463977 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/leaseSetAuthority.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/leaseSetAuthority.ts @@ -24,7 +24,7 @@ export function leaseSetAuthority( program: SwitchboardProgram, args: LeaseSetAuthorityArgs, accounts: LeaseSetAuthorityAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.lease, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/leaseWithdraw.ts b/javascript/solana.js/src/generated/oracle-program/instructions/leaseWithdraw.ts index 002850e23..dc05852d9 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/leaseWithdraw.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/leaseWithdraw.ts @@ -30,7 +30,7 @@ export function leaseWithdraw( program: SwitchboardProgram, args: LeaseWithdrawArgs, accounts: LeaseWithdrawAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.lease, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/oracleHeartbeat.ts b/javascript/solana.js/src/generated/oracle-program/instructions/oracleHeartbeat.ts index 55e4b3a26..089916e6f 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/oracleHeartbeat.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/oracleHeartbeat.ts @@ -28,7 +28,7 @@ export function oracleHeartbeat( program: SwitchboardProgram, args: OracleHeartbeatArgs, accounts: OracleHeartbeatAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.oracle, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/oracleInit.ts b/javascript/solana.js/src/generated/oracle-program/instructions/oracleInit.ts index 8f114d910..60dc007bd 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/oracleInit.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/oracleInit.ts @@ -26,7 +26,7 @@ export function oracleInit( program: SwitchboardProgram, args: OracleInitArgs, accounts: OracleInitAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.oracle, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/oracleQueueInit.ts b/javascript/solana.js/src/generated/oracle-program/instructions/oracleQueueInit.ts index ccd95bc72..7f5a9877d 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/oracleQueueInit.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/oracleQueueInit.ts @@ -27,7 +27,7 @@ export function oracleQueueInit( program: SwitchboardProgram, args: OracleQueueInitArgs, accounts: OracleQueueInitAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.oracleQueue, isSigner: true, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/oracleQueueSetConfig.ts b/javascript/solana.js/src/generated/oracle-program/instructions/oracleQueueSetConfig.ts index b35ed0247..7e0c1d635 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/oracleQueueSetConfig.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/oracleQueueSetConfig.ts @@ -23,7 +23,7 @@ export function oracleQueueSetConfig( program: SwitchboardProgram, args: OracleQueueSetConfigArgs, accounts: OracleQueueSetConfigAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.queue, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/oracleTeeHeartbeat.ts b/javascript/solana.js/src/generated/oracle-program/instructions/oracleTeeHeartbeat.ts index 057856d14..507f20f7b 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/oracleTeeHeartbeat.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/oracleTeeHeartbeat.ts @@ -30,7 +30,7 @@ export function oracleTeeHeartbeat( program: SwitchboardProgram, args: OracleTeeHeartbeatArgs, accounts: OracleTeeHeartbeatAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.oracle, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/oracleWithdraw.ts b/javascript/solana.js/src/generated/oracle-program/instructions/oracleWithdraw.ts index a293f64b5..f2ccee500 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/oracleWithdraw.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/oracleWithdraw.ts @@ -31,7 +31,7 @@ export function oracleWithdraw( program: SwitchboardProgram, args: OracleWithdrawArgs, accounts: OracleWithdrawAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.oracle, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/permissionInit.ts b/javascript/solana.js/src/generated/oracle-program/instructions/permissionInit.ts index 2a4700e90..ccb084daf 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/permissionInit.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/permissionInit.ts @@ -27,7 +27,7 @@ export function permissionInit( program: SwitchboardProgram, args: PermissionInitArgs, accounts: PermissionInitAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.permission, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/permissionSet.ts b/javascript/solana.js/src/generated/oracle-program/instructions/permissionSet.ts index 66efe083f..4c7b48785 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/permissionSet.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/permissionSet.ts @@ -23,7 +23,7 @@ export function permissionSet( program: SwitchboardProgram, args: PermissionSetArgs, accounts: PermissionSetAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.permission, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/programConfig.ts b/javascript/solana.js/src/generated/oracle-program/instructions/programConfig.ts index 8260c2576..2237dcbec 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/programConfig.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/programConfig.ts @@ -24,7 +24,7 @@ export function programConfig( program: SwitchboardProgram, args: ProgramConfigArgs, accounts: ProgramConfigAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.authority, isSigner: true, isWritable: false }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/programInit.ts b/javascript/solana.js/src/generated/oracle-program/instructions/programInit.ts index 0cbba748f..ca2867a46 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/programInit.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/programInit.ts @@ -27,7 +27,7 @@ export function programInit( program: SwitchboardProgram, args: ProgramInitArgs, accounts: ProgramInitAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.state, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/setBumps.ts b/javascript/solana.js/src/generated/oracle-program/instructions/setBumps.ts index 15341aa57..50f883547 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/setBumps.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/setBumps.ts @@ -20,7 +20,7 @@ export function setBumps( program: SwitchboardProgram, args: SetBumpsArgs, accounts: SetBumpsAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.state, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/vaultTransfer.ts b/javascript/solana.js/src/generated/oracle-program/instructions/vaultTransfer.ts index 2b381f8c3..747e81961 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/vaultTransfer.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/vaultTransfer.ts @@ -26,7 +26,7 @@ export function vaultTransfer( program: SwitchboardProgram, args: VaultTransferArgs, accounts: VaultTransferAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.state, isSigner: false, isWritable: false }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/vrfCloseAction.ts b/javascript/solana.js/src/generated/oracle-program/instructions/vrfCloseAction.ts index f1efbbead..bdc53cd41 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/vrfCloseAction.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/vrfCloseAction.ts @@ -29,7 +29,7 @@ export function vrfCloseAction( program: SwitchboardProgram, args: VrfCloseActionArgs, accounts: VrfCloseActionAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.authority, isSigner: true, isWritable: false }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/vrfInit.ts b/javascript/solana.js/src/generated/oracle-program/instructions/vrfInit.ts index 19ae42adc..8d98c9cba 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/vrfInit.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/vrfInit.ts @@ -25,7 +25,7 @@ export function vrfInit( program: SwitchboardProgram, args: VrfInitArgs, accounts: VrfInitAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.vrf, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteCloseAction.ts b/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteCloseAction.ts index d252faf21..00171329b 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteCloseAction.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteCloseAction.ts @@ -29,7 +29,7 @@ export function vrfLiteCloseAction( program: SwitchboardProgram, args: VrfLiteCloseActionArgs, accounts: VrfLiteCloseActionAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.authority, isSigner: true, isWritable: false }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteInit.ts b/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteInit.ts index 51361aa62..811456c45 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteInit.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteInit.ts @@ -32,7 +32,7 @@ export function vrfLiteInit( program: SwitchboardProgram, args: VrfLiteInitArgs, accounts: VrfLiteInitAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.authority, isSigner: false, isWritable: false }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteProveAndVerify.ts b/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteProveAndVerify.ts index 1d443b674..af3cccd1d 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteProveAndVerify.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteProveAndVerify.ts @@ -30,7 +30,7 @@ export function vrfLiteProveAndVerify( program: SwitchboardProgram, args: VrfLiteProveAndVerifyArgs, accounts: VrfLiteProveAndVerifyAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.vrfLite, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteRequestRandomness.ts b/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteRequestRandomness.ts index 1e36d2562..0fe6bbda1 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteRequestRandomness.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/vrfLiteRequestRandomness.ts @@ -31,7 +31,7 @@ export function vrfLiteRequestRandomness( program: SwitchboardProgram, args: VrfLiteRequestRandomnessArgs, accounts: VrfLiteRequestRandomnessAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.authority, isSigner: true, isWritable: false }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolAdd.ts b/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolAdd.ts index 324401d2c..0827d324e 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolAdd.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolAdd.ts @@ -24,7 +24,7 @@ export function vrfPoolAdd( program: SwitchboardProgram, args: VrfPoolAddArgs, accounts: VrfPoolAddAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.authority, isSigner: false, isWritable: false }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolInit.ts b/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolInit.ts index 3c175dda0..6f16b52c7 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolInit.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolInit.ts @@ -30,7 +30,7 @@ export function vrfPoolInit( program: SwitchboardProgram, args: VrfPoolInitArgs, accounts: VrfPoolInitAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.authority, isSigner: false, isWritable: false }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolRemove.ts b/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolRemove.ts index a51d3b854..6696f50a9 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolRemove.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolRemove.ts @@ -24,7 +24,7 @@ export function vrfPoolRemove( program: SwitchboardProgram, args: VrfPoolRemoveArgs, accounts: VrfPoolRemoveAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.authority, isSigner: true, isWritable: false }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolRequest.ts b/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolRequest.ts index 79440b281..7011479bd 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolRequest.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/vrfPoolRequest.ts @@ -31,7 +31,7 @@ export function vrfPoolRequest( program: SwitchboardProgram, args: VrfPoolRequestArgs, accounts: VrfPoolRequestAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.authority, isSigner: true, isWritable: false }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/vrfProveAndVerify.ts b/javascript/solana.js/src/generated/oracle-program/instructions/vrfProveAndVerify.ts index 58f61f760..0bf725878 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/vrfProveAndVerify.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/vrfProveAndVerify.ts @@ -30,7 +30,7 @@ export function vrfProveAndVerify( program: SwitchboardProgram, args: VrfProveAndVerifyArgs, accounts: VrfProveAndVerifyAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.vrf, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/vrfRequestRandomness.ts b/javascript/solana.js/src/generated/oracle-program/instructions/vrfRequestRandomness.ts index ce01b1f67..f37d8f5ce 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/vrfRequestRandomness.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/vrfRequestRandomness.ts @@ -33,7 +33,7 @@ export function vrfRequestRandomness( program: SwitchboardProgram, args: VrfRequestRandomnessArgs, accounts: VrfRequestRandomnessAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.authority, isSigner: true, isWritable: false }, diff --git a/javascript/solana.js/src/generated/oracle-program/instructions/vrfSetCallback.ts b/javascript/solana.js/src/generated/oracle-program/instructions/vrfSetCallback.ts index 11538e356..7c04d7ec4 100644 --- a/javascript/solana.js/src/generated/oracle-program/instructions/vrfSetCallback.ts +++ b/javascript/solana.js/src/generated/oracle-program/instructions/vrfSetCallback.ts @@ -23,7 +23,7 @@ export function vrfSetCallback( program: SwitchboardProgram, args: VrfSetCallbackArgs, accounts: VrfSetCallbackAccounts, - programId: PublicKey = program.programId + programId: PublicKey = program.oracleProgramId ) { const keys: Array = [ { pubkey: accounts.vrf, isSigner: false, isWritable: true }, diff --git a/javascript/solana.js/src/mint.ts b/javascript/solana.js/src/mint.ts index 91fd072e8..d03390e5a 100644 --- a/javascript/solana.js/src/mint.ts +++ b/javascript/solana.js/src/mint.ts @@ -21,7 +21,7 @@ export class Mint { constructor( readonly provider: anchor.AnchorProvider, - readonly mint: spl.Mint + readonly mint: { address: PublicKey; decimals: number } ) {} get address() { @@ -233,11 +233,18 @@ export class Mint { export class NativeMint extends Mint { public static address = Mint.native; + constructor(provider: anchor.AnchorProvider) { + const splMint = { + address: new PublicKey("So11111111111111111111111111111111111111112"), + decimals: 9, + }; + super(provider, splMint); + } + public static async load( provider: anchor.AnchorProvider ): Promise { - const splMint = await spl.getMint(provider.connection, Mint.native); - return new NativeMint(provider, splMint); + return new NativeMint(provider); } public async getOrCreateWrappedUser( diff --git a/javascript/solana.js/src/runner/env.ts b/javascript/solana.js/src/runner/env.ts new file mode 100644 index 000000000..1b13dc3f1 --- /dev/null +++ b/javascript/solana.js/src/runner/env.ts @@ -0,0 +1,91 @@ +import { SB_ATTESTATION_PID } from "../SwitchboardProgram.js"; + +import dotenv from "dotenv"; +import z from "zod"; +import { generateErrorMessage } from "zod-error"; +dotenv.config(); + +const envSchema = z.object({ + NODE_ENV: z + .enum(["development", "test", "production"]) + .default("development"), + IS_SIMULATION: z.coerce.boolean().default(false), + SWITCHBOARD: z.string().default(SB_ATTESTATION_PID.toBase58()), + FUNCTION_KEY: z.string(), + PAYER: z.string(), + VERIFIER: z.string(), + REWARD_RECEIVER: z.string(), + FUNCTION_DATA: z.string().optional(), + VERIFIER_ENCLAVE_SIGNER: z.string().optional(), + QUEUE_AUTHORITY: z.string().optional(), + FUNCTION_REQUEST_KEY: z.string().optional(), + FUNCTION_REQUEST_DATA: z.string().optional(), + CLUSTER: z + .enum(["mainnet-beta", "devnet", "localnet"]) + .default("mainnet-beta"), +}); + +const ENV = envSchema.parse(process.env); + +const getEnvIssues = (): z.ZodIssue[] | void => { + const result = envSchema.safeParse(process.env); + if (!result.success) return result.error.issues; + const env = envSchema.parse(process.env); +}; + +export function getEnv() { + const issues = getEnvIssues(); + if (issues) { + console.error("Invalid environment variables, check the errors below!"); + console.error( + generateErrorMessage(issues, { + delimiter: { error: "\\n" }, + }) + ); + process.exit(-1); + } + + return ENV; +} + +// export interface SolanaFunctionEnvironment { +// switchboard: PublicKey; +// functionKey: PublicKey; +// payer: PublicKey; +// verifier: PublicKey; +// rewardReceiver: PublicKey; +// functionData: FunctionAccountData; +// verifierEnclaveSigner: PublicKey; +// queueAuthority: PublicKey; +// functionRequestKey: PublicKey; +// functionRequestData: FunctionRequestAccountData; +// cluster: Omit | "localnet"; +// } + +// export async function loadEnv(): Promise { +// const issues = getEnvIssues(); +// if (issues) { +// console.error("Invalid environment variables, check the errors below!"); +// console.error( +// generateErrorMessage(issues, { +// delimiter: { error: "\\n" }, +// }) +// ); +// process.exit(-1); +// } + +// const env = envSchema.parse(process.env); +// if (env.IS_SIMULATION) { +// // idk, handle this differently somehow +// } +// const cluster = env.CLUSTER; + +// const switchboard = env.SWITCHBOARD +// ? new PublicKey(env.SWITCHBOARD) +// : SB_ATTESTATION_PID; + +// const payer = new PublicKey(env.PAYER); +// const verifier = new PublicKey(env.VERIFIER); + +// const functionKey = new PublicKey(env.FUNCTION_KEY); +// } diff --git a/javascript/solana.js/src/runner/functionResult.ts b/javascript/solana.js/src/runner/functionResult.ts new file mode 100644 index 000000000..d4328575d --- /dev/null +++ b/javascript/solana.js/src/runner/functionResult.ts @@ -0,0 +1,31 @@ +export interface EvmTransaction { + expiration_time_seconds: number; + gas_limit: string; + value: string; + to: number[]; + from: number[]; + data: number[]; +} + +export interface EVMFunctionResult { + txs: EvmTransaction[]; + signatures: number[][]; + call_ids: number[][]; + checksums: number[][]; +} + +export interface SOLFunctionResult { + serialized_tx: number[]; +} + +export type ChainResultInfo = EVMFunctionResult | SOLFunctionResult; + +export interface FunctionResult { + version: number; + quote: number[]; + fn_key: number[]; + signer: number[]; + fn_request_key: number[]; + fn_request_hash: number[]; + chain_result_info: ChainResultInfo; +} diff --git a/javascript/solana.js/src/runner/index.ts b/javascript/solana.js/src/runner/index.ts new file mode 100644 index 000000000..f24070c0d --- /dev/null +++ b/javascript/solana.js/src/runner/index.ts @@ -0,0 +1,8 @@ +export { + functionClose, + functionRequestClose, + functionRequestVerify, + functionVerify, +} from "../generated/attestation-program/instructions/index.js"; +export * from "./functionResult.js"; +export * from "./runner.js"; diff --git a/javascript/solana.js/src/runner/runner.ts b/javascript/solana.js/src/runner/runner.ts new file mode 100644 index 000000000..e53e4f721 --- /dev/null +++ b/javascript/solana.js/src/runner/runner.ts @@ -0,0 +1,500 @@ +import { AttestationQueueAccountData } from "../generated/attestation-program/accounts/AttestationQueueAccountData.js"; +import { FunctionAccountData } from "../generated/attestation-program/accounts/FunctionAccountData.js"; +import { FunctionRequestAccountData } from "../generated/attestation-program/accounts/FunctionRequestAccountData.js"; +import { VerifierAccountData } from "../generated/attestation-program/accounts/VerifierAccountData.js"; +import { functionRequestVerify } from "../generated/attestation-program/instructions/functionRequestVerify.js"; +import { functionVerify } from "../generated/attestation-program/instructions/functionVerify.js"; +import { AttestationPermissionAccount } from "../index.js"; +import { + SB_ATTESTATION_PID, + SwitchboardProgram, +} from "../SwitchboardProgram.js"; + +import { getEnv } from "./env.js"; +import type { FunctionResult } from "./functionResult.js"; + +import type { AnchorProvider } from "@coral-xyz/anchor"; +import { utils } from "@coral-xyz/anchor"; +import type { + Cluster, + Commitment, + TransactionInstruction, +} from "@solana/web3.js"; +import { + clusterApiUrl, + Connection, + Keypair, + PublicKey, + Transaction, + TransactionMessage, + VersionedTransaction, +} from "@solana/web3.js"; +import { BN, isBase58, isHex } from "@switchboard-xyz/common"; +import fetch from "cross-fetch"; +import crypto from "crypto"; +import dotenv from "dotenv"; +import fs from "fs"; +dotenv.config(); + +export interface SolanaFunctionEnvironment { + isSimulation?: boolean; + cluster: Omit | "localnet"; + switchboard: PublicKey; + // Required + functionKey: PublicKey; + // Required + payer: PublicKey; + // Required + verifier: PublicKey; + // Required + rewardReceiver: PublicKey; + + // optional, but may not be needed until ixn building + queueAuthority?: PublicKey; + verifierEnclaveSigner?: PublicKey; + + // optional, may need to async fetch + functionData?: Promise; + + functionRequestKey?: PublicKey; + functionRequestData?: Promise; +} + +function unixTimestamp() { + return Math.floor(Date.now() / 1000); +} + +export class FunctionRunner { + private readonly enclaveSigner: Keypair = Keypair.generate(); + private readonly start: number = unixTimestamp(); + + private constructor( + public readonly program: SwitchboardProgram, + private env: SolanaFunctionEnvironment + ) {} + + public isSimulation(): boolean { + return this.env.isSimulation ?? false; + } + + public get signer(): PublicKey { + return this.enclaveSigner.publicKey; + } + + public get connection(): Connection { + return this.program.provider.connection; + } + + // Required + public get payer(): PublicKey { + return this.env.payer; + } + + // Required + public get verifier(): PublicKey { + return this.env.verifier; + } + + // Required + public get rewardReceiver(): PublicKey { + return this.env.rewardReceiver; + } + + public get provider(): AnchorProvider { + return this.program.provider; + } + + // Required + public get functionKey(): PublicKey { + return this.env.functionKey; + } + + public get functionData(): Promise { + // return this.env.functionData; + if (!this.env.functionData) { + this.env.functionData = FunctionAccountData.fetch( + this.program, + this.env.functionKey + ) + .then((data) => { + if (!data) { + throw new Error("Function data not found!"); + } + return data; + }) + .catch((err) => { + this.env.functionData = undefined; + throw err; + }); + } + return this.env.functionData; + } + + public get functionRequestKey(): PublicKey { + if (!this.env.functionRequestKey) { + throw new Error("Function request key not found!"); + } + return this.env.functionRequestKey; + } + + public get functionRequestData(): Promise { + if (!this.env.functionRequestData) { + this.env.functionRequestData = FunctionRequestAccountData.fetch( + this.program, + this.functionRequestKey + ) + .then((data) => { + if (!data) { + throw new Error("Function request data not found!"); + } + return data; + }) + .catch((err) => { + this.env.functionRequestData = undefined; + throw err; + }); + } + + return this.env.functionRequestData; + } + + // public get verifierPermission(): PublicKey { + // return PublicKey.findProgramAddressSync( + // [ + // Buffer.from("PermissionAccountData"), + // this.env.queueAuthority.toBytes(), + // this.env.functionData.attestationQueue.toBytes(), + // this.env.verifier.toBytes(), + // ], + // this.program.attestationProgramId + // )[0]; + // } + + public static create( + rpcEndpoint?: string, + commitment: Commitment = "confirmed" + ): FunctionRunner { + const env = getEnv(); + + if (env.IS_SIMULATION) { + console.debug(`IS_SIMULATION: true`); + } + + const cluster = env.CLUSTER; + const connection = new Connection( + rpcEndpoint ?? cluster === "localnet" + ? "http://localhost:8899" + : clusterApiUrl(cluster), + { + commitment, + fetch: fetch, + } + ); + + const switchboard = env.SWITCHBOARD + ? new PublicKey(env.SWITCHBOARD) + : SB_ATTESTATION_PID; + + // TODO: make sync version using local IDLs + const program = SwitchboardProgram.from( + connection, + undefined, + undefined, + switchboard + ); + + // verifier provided env keys + const payer = new PublicKey(env.PAYER); + const verifier = new PublicKey(env.VERIFIER); + const rewardReceiver = new PublicKey(env.REWARD_RECEIVER); + + // load function data + const functionKey = new PublicKey(env.FUNCTION_KEY); + const functionData = + env.FUNCTION_DATA && isHex(env.FUNCTION_DATA) + ? Promise.resolve( + FunctionAccountData.decode( + Buffer.concat([ + FunctionAccountData.discriminator, + Buffer.from( + env.FUNCTION_DATA.startsWith("0x") + ? env.FUNCTION_DATA.slice(2) + : env.FUNCTION_DATA, + "hex" + ), + ]) + ) + ) + : undefined; + + // load verifier enclave signer + const verifierEnclaveSigner = + env.VERIFIER_ENCLAVE_SIGNER && isBase58(env.VERIFIER_ENCLAVE_SIGNER) + ? new PublicKey(env.VERIFIER_ENCLAVE_SIGNER) + : undefined; + + const queueAuthority = + env.QUEUE_AUTHORITY && isBase58(env.QUEUE_AUTHORITY) + ? new PublicKey(env.QUEUE_AUTHORITY) + : undefined; + + // load function request info if provided + const functionRequestKey = + env.FUNCTION_REQUEST_KEY && isBase58(env.FUNCTION_REQUEST_KEY) + ? new PublicKey(env.FUNCTION_REQUEST_KEY) + : undefined; + + const functionRequestData = !functionRequestKey + ? undefined + : env.FUNCTION_REQUEST_DATA && isHex(env.FUNCTION_REQUEST_DATA) + ? Promise.resolve( + FunctionRequestAccountData.decode( + Buffer.concat([ + FunctionRequestAccountData.discriminator, + Buffer.from( + env.FUNCTION_REQUEST_DATA.startsWith("0x") + ? env.FUNCTION_REQUEST_DATA.slice(2) + : env.FUNCTION_REQUEST_DATA, + "hex" + ), + ]) + ) + ) + : undefined; + + return new FunctionRunner(program, { + isSimulation: env.IS_SIMULATION ?? false, + cluster, + switchboard, + functionKey, + payer, + verifier, + rewardReceiver, + functionData, + verifierEnclaveSigner, + queueAuthority, + functionRequestKey, + functionRequestData, + }); + } + + private async loadQueueAuthority(): Promise { + if (!this.env.queueAuthority) { + this.env.queueAuthority = await (async () => { + const attestationQueueAccountData = + await AttestationQueueAccountData.fetch( + this.program, + ( + await this.functionData + ).attestationQueue + ); + if (!attestationQueueAccountData) { + throw new Error("AttestationQueue data not found!"); + } + return attestationQueueAccountData.authority; + })(); + } + + return this.env.queueAuthority; + } + + private async loadVerifierEnclaveSigner(): Promise { + if (!this.env.verifierEnclaveSigner) { + this.env.verifierEnclaveSigner = await (async () => { + const verifierAccountData = await VerifierAccountData.fetch( + this.program, + this.verifier + ); + if (!verifierAccountData) { + throw new Error("Verifier data not found!"); + } + return verifierAccountData.enclave.enclaveSigner; + })(); + } + + return this.env.verifierEnclaveSigner; + } + + public async getResult( + ixs: TransactionInstruction[] = [], + errorCode = 0 + ): Promise { + const quote = this.generateQuote(); + // @TODO: check this - will be the source of problems if wrong + const mrEnclave = quote.slice(432, 432 + 32); + console.log(`MR ENCLAVE: 0x${quote.slice(432, 432 + 32).toString("hex")}`); + + // TODO: verify this mrEnclave value is present in the function/request config + + const verifyIxn: TransactionInstruction = this.env.functionRequestKey + ? await this.buildFnRequestVerifyIxn(mrEnclave, errorCode) + : await this.buildFnVerifyIxn(mrEnclave, errorCode); + + const { blockhash } = await this.connection.getLatestBlockhash(); + + const transaction = new Transaction({ + feePayer: this.payer, + recentBlockhash: blockhash, + }).add(verifyIxn, ...ixs); + transaction.partialSign(this.enclaveSigner); + + return { + version: 1, + quote: Array.from(quote), + fn_key: Array.from(this.env.functionKey.toBytes()), + signer: Array.from(this.signer.toBytes()), + fn_request_key: this.env.functionRequestKey + ? Array.from(this.env.functionRequestKey.toBytes()) + : [], + fn_request_hash: [], // TODO: hash should be checked against + chain_result_info: { + serialized_tx: Array.from( + transaction.serialize({ + requireAllSignatures: false, + verifySignatures: false, + }) + ), + }, + }; + } + + public async emit( + ixs: TransactionInstruction[] = [], + errorCode = 0 + ): Promise { + try { + const functionResult = await this.getResult(ixs, errorCode); + console.info( + `FN_OUT: ${Buffer.from(JSON.stringify(functionResult)).toString("hex")}` + ); + } catch (error) { + throw new Error(`failed to get verify ixn: ${error}`); + } + } + + public async emitError(errorCode: 0): Promise { + try { + const functionResult = await this.getResult([], errorCode); + console.info( + `FN_OUT: ${Buffer.from(JSON.stringify(functionResult)).toString("hex")}` + ); + } catch (error) { + throw new Error(`failed to get verify ixn: ${error}`); + } + } + + private generateQuote(): Buffer { + // get sgx quote + try { + fs.accessSync("/dev/attestation/quote"); + } catch (err) { + if (this.env.isSimulation) { + console.log("WARNING: NOT IN TEE / NO QUOTE GENERATED"); + } else { + throw new Error(`NOT IN TEE / FAILED TO GENERATE QUOTE`); + } + } + + const hash = crypto.createHash("sha256"); + hash.update(this.signer.toBytes()); + const data = Array.from(hash.digest()); + data.length = 64; + + fs.writeFileSync("/dev/attestation/user_report_data", Buffer.from(data)); + const quote = fs.readFileSync("/dev/attestation/quote"); + + return quote; + } + + private async buildFnVerifyIxn( + mrEnclave: Buffer, + errorCode = 0 + ): Promise { + const functionData = await this.functionData; + + const queueAuthority = await this.loadQueueAuthority(); + const verifierPermission = AttestationPermissionAccount.fromSeed( + this.program, + queueAuthority, + functionData.attestationQueue, + this.verifier + ); + + const verifierEnclaveSigner = await this.loadVerifierEnclaveSigner(); + + return functionVerify( + this.program, + { + params: { + observedTime: new BN(unixTimestamp()), + nextAllowedTimestamp: new BN(unixTimestamp() + 100), + errorCode: errorCode, + mrEnclave: Array.from(mrEnclave), + }, + }, + { + function: this.env.functionKey, + functionEnclaveSigner: this.signer, + verifier: this.env.verifier, + verifierSigner: verifierEnclaveSigner, + verifierPermission: verifierPermission.publicKey, + escrowWallet: functionData.escrowWallet, + escrowTokenWallet: functionData.escrowTokenWallet, + attestationQueue: functionData.attestationQueue, + receiver: this.env.rewardReceiver, + tokenProgram: utils.token.TOKEN_PROGRAM_ID, + } + ); + } + + private async buildFnRequestVerifyIxn( + mrEnclave: Buffer, + errorCode = 0 + ): Promise { + if (!this.env.functionRequestData) { + throw new Error( + `Need to provide the function request data to build this instruction` + ); + } + + const functionData = await this.functionData; + const functionRequestData = await this.functionRequestData; + + const queueAuthority = await this.loadQueueAuthority(); + const verifierPermission = AttestationPermissionAccount.fromSeed( + this.program, + queueAuthority, + functionData.attestationQueue, + this.verifier + ); + + const verifierEnclaveSigner = await this.loadVerifierEnclaveSigner(); + + return functionRequestVerify( + this.program, + { + params: { + observedTime: new BN(unixTimestamp()), + errorCode: errorCode, + mrEnclave: Array.from(mrEnclave), + requestSlot: functionRequestData.activeRequest.requestSlot, + containerParamsHash: functionRequestData.containerParamsHash, + }, + }, + { + request: this.env.functionRequestKey!, + functionEnclaveSigner: this.signer, + escrow: functionRequestData.escrow, + function: this.env.functionKey, + functionEscrow: functionData.escrowTokenWallet, + verifierQuote: this.env.verifier, + verifierEnclaveSigner: verifierEnclaveSigner, + verifierPermission: verifierPermission.publicKey, + state: this.program.attestationProgramState.publicKey, + attestationQueue: functionData.attestationQueue, + receiver: this.env.rewardReceiver, + tokenProgram: utils.token.TOKEN_PROGRAM_ID, + } + ); + } +} diff --git a/javascript/solana.js/src/types.ts b/javascript/solana.js/src/types.ts index 112c07489..44eb9b5f0 100644 --- a/javascript/solana.js/src/types.ts +++ b/javascript/solana.js/src/types.ts @@ -124,13 +124,13 @@ export type LoadedJobDefinition = LoadedAccountDefinition< job: OracleJob; }; -export class MrEnclave { - public readonly mrEnclave: Uint8Array; +// export class MrEnclave { +// public readonly mrEnclave: Uint8Array; - public constructor(mrEnclave: string | Buffer | Uint8Array | number[]) { - this.mrEnclave = - typeof mrEnclave === "string" - ? new Uint8Array(Buffer.from(mrEnclave)) - : new Uint8Array(mrEnclave); - } -} +// public constructor(mrEnclave: string | Buffer | Uint8Array | number[]) { +// this.mrEnclave = +// typeof mrEnclave === "string" +// ? new Uint8Array(Buffer.from(mrEnclave)) +// : new Uint8Array(mrEnclave); +// } +// } diff --git a/javascript/solana.js/src/utils.ts b/javascript/solana.js/src/utils.ts index 52bf23001..e6d04beaf 100644 --- a/javascript/solana.js/src/utils.ts +++ b/javascript/solana.js/src/utils.ts @@ -18,6 +18,12 @@ import fs from "fs"; import os from "os"; import path from "path"; +export { + combineMrEnclaveSets, + containsMrEnclave, + filterEmptyMrEnclaves, +} from "@switchboard-xyz/common"; + export function handleOptionalPubkeys( ixn: TransactionInstruction ): TransactionInstruction { @@ -244,19 +250,6 @@ export function parseRawBuffer(rawBuffer: RawBuffer, size = 32): Uint8Array { ); } -export function containsMrEnclave( - mrEnclaves: number[][], - targetMrEnclave: number[] | Uint8Array -): boolean { - return mrEnclaves.some((arr) => { - if (arr.length !== targetMrEnclave.length) return false; - for (let i = 0; i < arr.length; i++) { - if (arr[i] !== targetMrEnclave[i]) return false; - } - return true; - }); -} - /** * Validate a cron schedule and return a valid 6 element cron string which includes seconds * @param cronSchedule - the cron string to validate diff --git a/javascript/solana.js/test/attestation-function.spec.ts b/javascript/solana.js/test/attestation-function.spec.ts index eb8dbede7..a33a5065e 100644 --- a/javascript/solana.js/test/attestation-function.spec.ts +++ b/javascript/solana.js/test/attestation-function.spec.ts @@ -1,6 +1,5 @@ import "mocha"; -import { functionVerify } from "../src/generated/index.js"; import type { AttestationQueueAccount } from "../src/index.js"; import type { VerifierAccount } from "../src/index.js"; import * as sbv2 from "../src/index.js"; @@ -9,8 +8,7 @@ import type { TestContext } from "./utils.js"; import { printLogs, setupTest } from "./utils.js"; import * as anchor from "@coral-xyz/anchor"; -import { NATIVE_MINT } from "@solana/spl-token"; -import { Keypair, PublicKey, TransactionInstruction } from "@solana/web3.js"; +import { Keypair } from "@solana/web3.js"; import { BN, sleep, toUtf8 } from "@switchboard-xyz/common"; import assert from "assert"; @@ -106,7 +104,6 @@ describe("Function Tests", () => { { name: "FUNCTION_NAME", metadata: "FUNCTION_METADATA", - schedule: "* * * * *", container: "containerId", version: "1.0.0", mrEnclave, @@ -346,7 +343,6 @@ describe("Function Tests", () => { { name: "FUNCTION_NAME", metadata: "FUNCTION_METADATA", - schedule: "* * * * *", container: "containerId", version: "1.0.0", mrEnclave, @@ -385,7 +381,6 @@ describe("Function Tests", () => { { name: "FUNCTION_NAME", metadata: "FUNCTION_METADATA", - schedule: "* * * * *", container: "containerId", version: "1.0.0", mrEnclave, diff --git a/javascript/solana.js/test/new_wallet.spec.ts b/javascript/solana.js/test/new_wallet.spec.ts index f7858fafc..85c311946 100644 --- a/javascript/solana.js/test/new_wallet.spec.ts +++ b/javascript/solana.js/test/new_wallet.spec.ts @@ -77,7 +77,6 @@ describe("NEW Switchboard Wallet Tests", () => { program, { container: "", - schedule: "* * * * * *", attestationQueue: switchboard.attestationQueue.account, }, undefined, diff --git a/javascript/solana.js/test/tsconfig.json b/javascript/solana.js/test/tsconfig.json index d97e7ba7b..7fd5d8c94 100644 --- a/javascript/solana.js/test/tsconfig.json +++ b/javascript/solana.js/test/tsconfig.json @@ -13,7 +13,7 @@ "node", "mocha" ], - "module": "ESNext", + "module": "NodeNext", "allowJs": true, "rootDir": "../", "resolveJsonModule": true diff --git a/javascript/solana.js/tsconfig.json b/javascript/solana.js/tsconfig.json index c35fbf1a8..c3209cb03 100644 --- a/javascript/solana.js/tsconfig.json +++ b/javascript/solana.js/tsconfig.json @@ -9,7 +9,7 @@ "src/**/*" ], "compilerOptions": { - "module": "ESNext", + "module": "NodeNext", "target": "es2022", "lib": [ "ES2021", @@ -37,6 +37,7 @@ "src/TransactionObject.ts", "src/accounts/AggregatorAccount.ts", "src/generated/index.ts", + "src/runner/index.ts", "src/generated/accounts.ts", "src/generated/instructions.ts", "src/generated/types.ts", diff --git a/rust/switchboard-solana/Cargo.anchor27.lock b/rust/switchboard-solana/Cargo.anchor27.lock index 035898ff6..dba9bf2e3 100644 --- a/rust/switchboard-solana/Cargo.anchor27.lock +++ b/rust/switchboard-solana/Cargo.anchor27.lock @@ -441,6 +441,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + [[package]] name = "base64" version = "0.12.3" @@ -455,9 +461,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" @@ -839,6 +845,22 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "common-multipart-rfc7578" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baee326bc603965b0f26583e1ecd7c111c41b49bd92a344897476a352798869" +dependencies = [ + "bytes", + "futures-core", + "futures-util", + "http", + "mime", + "mime_guess", + "rand 0.8.5", + "thiserror", +] + [[package]] name = "console" version = "0.15.7" @@ -906,6 +928,15 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + [[package]] name = "cpufeatures" version = "0.2.9" @@ -1038,12 +1069,45 @@ dependencies = [ "zeroize", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.0", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +[[package]] +name = "data-encoding-macro" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" +dependencies = [ + "data-encoding", + "syn 1.0.109", +] + [[package]] name = "der" version = "0.4.5" @@ -1101,6 +1165,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "digest" version = "0.9.0" @@ -1121,6 +1191,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -1131,6 +1210,17 @@ dependencies = [ "dirs-sys-next", ] +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -1176,6 +1266,12 @@ dependencies = [ "syn 0.15.44", ] +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + [[package]] name = "eager" version = "0.1.0" @@ -1270,6 +1366,15 @@ dependencies = [ "syn 2.0.33", ] +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "log", +] + [[package]] name = "env_logger" version = "0.9.3" @@ -1298,6 +1403,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "erased-serde" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +dependencies = [ + "serde", +] + [[package]] name = "errno" version = "0.3.3" @@ -1719,6 +1833,19 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-multipart-rfc7578" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb2cf73e96e9925f4bed948e763aa2901c2f1a3a5f713ee41917433ced6671" +dependencies = [ + "bytes", + "common-multipart-rfc7578", + "futures-core", + "http", + "hyper", +] + [[package]] name = "hyper-rustls" version = "0.24.1" @@ -1836,6 +1963,49 @@ dependencies = [ "generic-array", ] +[[package]] +name = "ipfs-api-backend-hyper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9d131b408b4caafe1e7c00d410a09ad3eb7e3ab68690cf668e86904b2176b4" +dependencies = [ + "async-trait", + "base64 0.13.1", + "bytes", + "futures", + "http", + "hyper", + "hyper-multipart-rfc7578", + "ipfs-api-prelude", + "thiserror", +] + +[[package]] +name = "ipfs-api-prelude" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b74065805db266ba2c6edbd670b23c4714824a955628472b2e46cc9f3a869cb" +dependencies = [ + "async-trait", + "bytes", + "cfg-if", + "common-multipart-rfc7578", + "dirs", + "futures", + "http", + "multiaddr", + "multibase", + "serde", + "serde_json", + "serde_urlencoded", + "thiserror", + "tokio", + "tokio-util", + "tracing", + "typed-builder", + "walkdir", +] + [[package]] name = "ipnet" version = "2.8.0" @@ -1875,6 +2045,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json_env_logger" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e2ec540ea0448b187d3a8b4a9f13e75527d06ef76b3a2baa1cd982aecb62ce2" +dependencies = [ + "env_logger 0.7.1", + "kv-log-macro", + "log", + "serde_json", +] + [[package]] name = "jsonrpc-core" version = "18.0.0" @@ -1899,6 +2081,15 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -2018,6 +2209,9 @@ name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +dependencies = [ + "value-bag", +] [[package]] name = "memchr" @@ -2070,6 +2264,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2096,6 +2300,61 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "multiaddr" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b36f567c7099511fa8612bbbb52dda2419ce0bdbacf31714e3a5ffdb766d3bd" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", + "log", + "multibase", + "multihash", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint", + "url", +] + +[[package]] +name = "multibase" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +dependencies = [ + "base-x", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "multihash" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40" +dependencies = [ + "core2", + "multihash-derive", + "unsigned-varint", +] + +[[package]] +name = "multihash-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc076939022111618a5026d3be019fd8b366e76314538ff9a1b59ffbcbf98bcd" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2 1.0.67", + "quote 1.0.33", + "syn 1.0.109", + "synstructure", +] + [[package]] name = "native-tls" version = "0.2.11" @@ -2526,6 +2785,16 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +dependencies = [ + "diff", + "yansi", +] + [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -2545,6 +2814,30 @@ dependencies = [ "toml_edit", ] +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2 1.0.67", + "quote 1.0.33", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2 1.0.67", + "quote 1.0.33", + "version_check", +] + [[package]] name = "proc-macro2" version = "0.4.30" @@ -2857,7 +3150,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ "async-compression", - "base64 0.21.4", + "base64 0.21.5", "bytes", "encoding_rs", "futures-core", @@ -3079,7 +3372,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", ] [[package]] @@ -3104,6 +3397,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.22" @@ -3193,6 +3495,15 @@ dependencies = [ "syn 2.0.33", ] +[[package]] +name = "serde_fmt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" +dependencies = [ + "serde", +] + [[package]] name = "serde_json" version = "1.0.107" @@ -3590,7 +3901,7 @@ version = "1.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06aa701c49493e93085dd1e800c05475baca15a9d4d527b59794f2ed0b66e055" dependencies = [ - "env_logger", + "env_logger 0.9.3", "lazy_static", "log", ] @@ -4076,31 +4387,113 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" +[[package]] +name = "sval" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15df12a8db7c216a04b4b438f90d50d5335cd38f161b56389c9f5c9d96d0873" + +[[package]] +name = "sval_buffer" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e80556bc8acea0446e574ce542ad6114a76a0237f28a842bc01ca3ea98f479" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d93d2259edb1d7b4316179f0a98c62e3ffc726f47ab200e07cfe382771f57b8" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532f7f882226f7a5a4656f5151224aaebf8217e0d539cb1595b831bace921343" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e03bd8aa0ae6ee018f7ae95c9714577687a4415bd1a5f19b26e34695f7e072" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_ref" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75ed054f2fb8c2a0ab5d36c1ec57b412919700099fc5e32ad8e7a38b23e1a9e1" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff191c4ff05b67e3844c161021427646cde5d6624597958be158357d9200586" +dependencies = [ + "serde", + "sval", + "sval_buffer", + "sval_fmt", +] + [[package]] name = "switchboard-common" -version = "0.8.20" +version = "0.11.0" dependencies = [ + "async-trait", + "base64 0.21.5", "envy", + "futures", "getrandom 0.2.10", "hex", + "ipfs-api-backend-hyper", + "ipfs-api-prelude", + "log", "serde", "serde_json", "sgx-quote", "sha2 0.10.7", + "sha3 0.10.8", ] [[package]] name = "switchboard-solana" -version = "0.27.25" +version = "0.27.70" dependencies = [ "anchor-client", "anchor-lang", "anchor-spl", + "base64 0.21.5", "bincode", "bytemuck", "chrono", "cron", + "dashmap", + "futures", "hex", + "json_env_logger", + "kv-log-macro", + "log", + "pretty_assertions", "rand 0.8.5", "reqwest", "rsa", @@ -4108,15 +4501,28 @@ dependencies = [ "serde", "serde_json", "sgx-quote", + "sha2 0.10.7", + "solana-account-decoder", "solana-address-lookup-table-program", "solana-client", "solana-program", "superslice", "switchboard-common", + "switchboard-solana-macros", "tokio", "url", ] +[[package]] +name = "switchboard-solana-macros" +version = "0.2.1" +dependencies = [ + "dotenvy", + "proc-macro2 1.0.67", + "quote 1.0.33", + "syn 2.0.33", +] + [[package]] name = "syn" version = "0.15.44" @@ -4289,9 +4695,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.32.0" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ "backtrace", "bytes", @@ -4481,12 +4887,32 @@ dependencies = [ "webpki-roots 0.22.6", ] +[[package]] +name = "typed-builder" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c" +dependencies = [ + "proc-macro2 1.0.67", + "quote 1.0.33", + "syn 1.0.109", +] + [[package]] name = "typenum" version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.13" @@ -4542,6 +4968,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "unsigned-varint" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" + [[package]] name = "untrusted" version = "0.7.1" @@ -4581,6 +5013,42 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +[[package]] +name = "value-bag" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a72e1902dde2bd6441347de2b70b7f5d59bf157c6c62f0c44572607a1d55bbe" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ba39dc791ecb35baad371a3fc04c6eab688c04937d2e0ac6c22b612c0357bf" +dependencies = [ + "erased-serde", + "serde", + "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e06c10810a57bbf45778d023d432a50a1daa7d185991ae06bcfb6c654d0945" +dependencies = [ + "sval", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", +] + [[package]] name = "vcpkg" version = "0.2.15" @@ -4599,6 +5067,16 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -4948,6 +5426,12 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + [[package]] name = "yasna" version = "0.5.2" diff --git a/rust/switchboard-solana/Cargo.anchor27.toml b/rust/switchboard-solana/Cargo.anchor27.toml index d98abd29b..4b2beaa39 100644 --- a/rust/switchboard-solana/Cargo.anchor27.toml +++ b/rust/switchboard-solana/Cargo.anchor27.toml @@ -1,7 +1,8 @@ [package] name = "switchboard-solana" -version = "0.27.26" +version = "0.27.70" edition = "2021" +resolver = "2" description = "A Rust library to interact with Switchboard accounts." readme = "README.md" keywords = ["switchboard", "oracle", "solana"] @@ -18,7 +19,10 @@ doctest = false default = ["cpi"] no-entrypoint = [] cpi = ["no-entrypoint"] -secrets = ["rand", "rsa", "reqwest", "serde", "serde_json"] +secrets = ["rand", "rsa", "reqwest"] +macros = ["switchboard-solana-macros"] +ipfs = ["switchboard-common/ipfs"] +all = ["secrets", "macros", "ipfs"] [dependencies] anchor-spl = "0.27.0" @@ -27,32 +31,46 @@ solana-address-lookup-table-program = "=1.14.16" rust_decimal = "^1" bytemuck = "^1" superslice = "1" +log = { version = "0.4", features = ["kv_unstable", "kv_unstable_std"] } +kv-log-macro = "1.0" +switchboard-solana-macros = { version = "0.2.1", path = "../switchboard-solana-macros", optional = true, features = [ + "dotenv", +] } [target.'cfg(target_os = "solana")'.dependencies] -switchboard-common = { version = "0.8.20", path = "../switchboard-common" } +switchboard-common = { version = "0.11.0", path = "../switchboard-common" } anchor-lang = { version = "0.27.0" } [target.'cfg(not(target_os = "solana"))'.dependencies] -switchboard-common = { version = "0.8.20", path = "../switchboard-common", features = [ - "client", - "solana", -] } +switchboard-common = { version = "0.11.0", features = [ + "client", +], path = "../switchboard-common" } anchor-client = { version = "0.27.0" } solana-client = "=1.14.16" +solana-account-decoder = "=1.14.16" +base64 = "0.21.4" bincode = { version = "^1" } sgx-quote = { version = "0.1.0" } cron = { version = "0.12.0" } chrono = { version = "0.4.25" } +futures = "0.3" hex = "0.4.3" tokio = "1" url = "2.4" +serde = { version = "^1", features = ["derive"] } +serde_json = { version = "^1" } +sha2 = "0.10.6" +dashmap = "5.5.3" # Secrets Dependencies rsa = { version = "0.5.0", optional = true } reqwest = { version = "0.11", features = ["json"], optional = true } rand = { version = "0.8.5", optional = true } -serde = { version = "^1", features = ["derive"], optional = true } -serde_json = { version = "^1", optional = true } [package.metadata.docs.rs] rustdoc-args = ["--cfg", "doc_cfg"] + +[dev-dependencies] +json_env_logger = "0.1" +tokio = { version = "1", features = ["full"] } +pretty_assertions = "1.4.0" diff --git a/rust/switchboard-solana/Cargo.anchor28.lock b/rust/switchboard-solana/Cargo.anchor28.lock new file mode 100644 index 000000000..a13dadb53 --- /dev/null +++ b/rust/switchboard-solana/Cargo.anchor28.lock @@ -0,0 +1,6152 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589c637f0e68c877bbd59a4599bbe849cac8e5f3e4b5a3ebae8f528cd218dcdc" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom 0.2.10", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "getrandom 0.2.10", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "anchor-attribute-access-control" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faa5be5b72abea167f87c868379ba3c2be356bfca9e6f474fd055fa0f7eeb4f2" +dependencies = [ + "anchor-syn", + "anyhow", + "proc-macro2 1.0.69", + "quote 1.0.32", + "regex", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-account" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f468970344c7c9f9d03b4da854fd7c54f21305059f53789d0045c1dd803f0018" +dependencies = [ + "anchor-syn", + "anyhow", + "bs58 0.5.0", + "proc-macro2 1.0.69", + "quote 1.0.32", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-constant" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59948e7f9ef8144c2aefb3f32a40c5fce2798baeec765ba038389e82301017ef" +dependencies = [ + "anchor-syn", + "proc-macro2 1.0.69", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-error" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc753c9d1c7981cb8948cf7e162fb0f64558999c0413058e2d43df1df5448086" +dependencies = [ + "anchor-syn", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-event" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38b4e172ba1b52078f53fdc9f11e3dc0668ad27997838a0aad2d148afac8c97" +dependencies = [ + "anchor-syn", + "anyhow", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-program" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eebd21543606ab61e2d83d9da37d24d3886a49f390f9c43a1964735e8c0f0d5" +dependencies = [ + "anchor-syn", + "anyhow", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "anchor-client" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8434a6bf33efba0c93157f7fa2fafac658cb26ab75396886dcedd87c2a8ad445" +dependencies = [ + "anchor-lang", + "anyhow", + "futures", + "regex", + "serde", + "solana-account-decoder", + "solana-client", + "solana-sdk", + "thiserror", + "tokio", + "url", +] + +[[package]] +name = "anchor-derive-accounts" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec4720d899b3686396cced9508f23dab420f1308344456ec78ef76f98fda42af" +dependencies = [ + "anchor-syn", + "anyhow", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-space" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f495e85480bd96ddeb77b71d499247c7d4e8b501e75ecb234e9ef7ae7bd6552a" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "anchor-lang" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d2d4b20100f1310a774aba3471ef268e5c4ba4d5c28c0bbe663c2658acbc414" +dependencies = [ + "anchor-attribute-access-control", + "anchor-attribute-account", + "anchor-attribute-constant", + "anchor-attribute-error", + "anchor-attribute-event", + "anchor-attribute-program", + "anchor-derive-accounts", + "anchor-derive-space", + "arrayref", + "base64 0.13.1", + "bincode", + "borsh 0.10.3", + "bytemuck", + "getrandom 0.2.10", + "solana-program", + "thiserror", +] + +[[package]] +name = "anchor-spl" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78f860599da1c2354e7234c768783049eb42e2f54509ecfc942d2e0076a2da7b" +dependencies = [ + "anchor-lang", + "solana-program", + "spl-associated-token-account 1.1.3", + "spl-token 3.5.0", + "spl-token-2022 0.6.1", +] + +[[package]] +name = "anchor-syn" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a125e4b0cc046cfec58f5aa25038e34cf440151d58f0db3afc55308251fe936d" +dependencies = [ + "anyhow", + "bs58 0.5.0", + "heck", + "proc-macro2 1.0.69", + "quote 1.0.32", + "serde", + "serde_json", + "sha2 0.10.7", + "syn 1.0.109", + "thiserror", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" + +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.7", + "itertools", + "num-bigint 0.4.4", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint 0.4.4", + "num-traits", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint 0.4.4", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "array-bytes" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ad284aeb45c13f2fb4f084de4a420ebf447423bdf9386c0540ce33cb3ef4b8c" + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "ascii" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" + +[[package]] +name = "asn1-rs" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom 7.1.3", + "num-traits", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "assert_matches" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-compression" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f658e2baef915ba0f26f1f7c42bfb8e12f532a01f449a090ded75ae7a07e9ba2" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-mutex" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake3" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" +dependencies = [ + "arrayref", + "arrayvec 0.7.4", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "borsh" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" +dependencies = [ + "borsh-derive 0.9.3", + "hashbrown 0.11.2", +] + +[[package]] +name = "borsh" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" +dependencies = [ + "borsh-derive 0.10.3", + "hashbrown 0.13.2", +] + +[[package]] +name = "borsh-derive" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" +dependencies = [ + "borsh-derive-internal 0.9.3", + "borsh-schema-derive-internal 0.9.3", + "proc-macro-crate 0.1.5", + "proc-macro2 1.0.69", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" +dependencies = [ + "borsh-derive-internal 0.10.3", + "borsh-schema-derive-internal 0.10.3", + "proc-macro-crate 0.1.5", + "proc-macro2 1.0.69", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "brotli" +version = "3.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "bv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] + +[[package]] +name = "bytecheck" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "bytemuck" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "caps" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190baaad529bcfbde9e1a19022c42781bdb6ff9de25721abdb8fd98c0807730b" +dependencies = [ + "libc", + "thiserror", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.48.1", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags 1.3.2", + "strsim 0.8.0", + "textwrap 0.11.0", + "unicode-width", + "vec_map", +] + +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_lex", + "indexmap", + "once_cell", + "strsim 0.10.0", + "termcolor", + "textwrap 0.16.0", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "combine" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" +dependencies = [ + "ascii", + "byteorder", + "either", + "memchr", + "unreachable", +] + +[[package]] +name = "common-multipart-rfc7578" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baee326bc603965b0f26583e1ecd7c111c41b49bd92a344897476a352798869" +dependencies = [ + "bytes", + "futures-core", + "futures-util", + "http", + "mime", + "mime_guess", + "rand 0.8.5", + "thiserror", +] + +[[package]] +name = "concurrent-queue" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "console" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.45.0", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "const-oid" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" + +[[package]] +name = "const-oid" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" + +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "cron" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ff76b51e4c068c52bfd2866e1567bee7c567ae8f24ada09fd4307019e25eab7" +dependencies = [ + "chrono", + "nom 7.1.3", + "once_cell", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset 0.9.0", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2 1.0.69", + "quote 1.0.32", + "strsim 0.10.0", + "syn 2.0.28", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.1", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" + +[[package]] +name = "data-encoding-macro" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" +dependencies = [ + "data-encoding", + "syn 1.0.109", +] + +[[package]] +name = "der" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" +dependencies = [ + "const-oid 0.6.2", + "crypto-bigint", +] + +[[package]] +name = "der" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +dependencies = [ + "const-oid 0.7.1", +] + +[[package]] +name = "der-parser" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom 7.1.3", + "num-bigint 0.4.4", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "deranged" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" + +[[package]] +name = "derivation-path" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "dialoguer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59c6f2989294b9a498d3ad5491a79c6deb604617378e1cdc4bfc1c1361fe2f87" +dependencies = [ + "console", + "shell-words", + "tempfile", + "zeroize", +] + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "dlopen" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e80ad39f814a9abe68583cd50a2d45c8a67561c3361ab8da240587dda80937" +dependencies = [ + "dlopen_derive", + "lazy_static", + "libc", + "winapi", +] + +[[package]] +name = "dlopen_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f236d9e1b1fbd81cea0f9cbdc8dcc7e8ebcd80e6659cd7cb2ad5f6c05946c581" +dependencies = [ + "libc", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "eager" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abe71d579d1812060163dff96056261deb5bf6729b100fa2e36a68b9649ba3d3" + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-dalek-bip32" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d2be62a4061b872c8c0873ee4fc6f101ce7b889d039f019c5fa2af471a59908" +dependencies = [ + "derivation-path", + "ed25519-dalek", + "hmac 0.12.1", + "sha2 0.10.7", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum-iterator" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7add3873b5dd076766ee79c8e406ad1a472c385476b9e38849f8eec24f1be689" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "log", +] + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "envy" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f47e0157f2cb54f5ae1bd371b30a2ae4311e1c028f575cd4e81de7353215965" +dependencies = [ + "serde", +] + +[[package]] +name = "erased-serde" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +dependencies = [ + "serde", +] + +[[package]] +name = "errno" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "flate2" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "serde", + "typenum", + "version_check", +] + +[[package]] +name = "gethostname" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "goblin" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7666983ed0dd8d21a6f6576ee00053ca0926fb281a5522577a4dbd0f1b54143" +dependencies = [ + "log", + "plain", + "scroll", +] + +[[package]] +name = "h2" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[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.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.3", +] + +[[package]] +name = "hashbrown" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "histogram" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cb882ccb290b8646e554b157ab0b71e64e8d5bef775cd66b6531e52d302669" + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", +] + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.9", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-multipart-rfc7578" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb2cf73e96e9925f4bed948e763aa2901c2f1a3a5f713ee41917433ced6671" +dependencies = [ + "bytes", + "common-multipart-rfc7578", + "futures-core", + "http", + "hyper", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls 0.21.7", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "rayon", + "serde", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indicatif" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipfs-api-backend-hyper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9d131b408b4caafe1e7c00d410a09ad3eb7e3ab68690cf668e86904b2176b4" +dependencies = [ + "async-trait", + "base64 0.13.1", + "bytes", + "futures", + "http", + "hyper", + "hyper-multipart-rfc7578", + "ipfs-api-prelude", + "thiserror", +] + +[[package]] +name = "ipfs-api-prelude" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b74065805db266ba2c6edbd670b23c4714824a955628472b2e46cc9f3a869cb" +dependencies = [ + "async-trait", + "bytes", + "cfg-if", + "common-multipart-rfc7578", + "dirs", + "futures", + "http", + "multiaddr", + "multibase", + "serde", + "serde_json", + "serde_urlencoded", + "thiserror", + "tokio", + "tokio-util", + "tracing", + "typed-builder", + "walkdir", +] + +[[package]] +name = "ipnet" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "jobserver" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json_env_logger" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e2ec540ea0448b187d3a8b4a9f13e75527d06ef76b3a2baa1cd982aecb62ce2" +dependencies = [ + "env_logger 0.7.1", + "kv-log-macro", + "log", + "serde_json", +] + +[[package]] +name = "jsonrpc-core" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +dependencies = [ + "futures", + "futures-executor", + "futures-util", + "log", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "lexical-core" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" +dependencies = [ + "arrayvec 0.5.2", + "bitflags 1.3.2", + "cfg-if", + "ryu", + "static_assertions", +] + +[[package]] +name = "libc" +version = "0.2.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" + +[[package]] +name = "libm" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.3.3", + "libc", + "redox_syscall 0.4.1", +] + +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +dependencies = [ + "value-bag", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "multiaddr" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b36f567c7099511fa8612bbbb52dda2419ce0bdbacf31714e3a5ffdb766d3bd" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", + "log", + "multibase", + "multihash", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint", + "url", +] + +[[package]] +name = "multibase" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +dependencies = [ + "base-x", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "multihash" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40" +dependencies = [ + "core2", + "multihash-derive", + "unsigned-varint", +] + +[[package]] +name = "multihash-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro-error", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", + "synstructure", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", + "pin-utils", +] + +[[package]] +name = "nom" +version = "5.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b" +dependencies = [ + "lexical-core", + "memchr", + "version_check", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" +dependencies = [ + "num-bigint 0.2.6", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint-dig" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9bc3e36fd683e004fd59c64a425e0e991616f5a8b617c3b9a933a93c168facc" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-complex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "num-derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint 0.2.6", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.2", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive 0.5.11", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive 0.6.1", +] + +[[package]] +name = "num_enum" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb" +dependencies = [ + "num_enum_derive 0.7.0", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "oid-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +dependencies = [ + "asn1-rs", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl" +version = "0.10.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +dependencies = [ + "bitflags 2.3.3", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "os_str_bytes" +version = "6.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.3.5", + "smallvec", + "windows-targets 0.48.1", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pbkdf2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +dependencies = [ + "crypto-mac", +] + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "pem-rfc7468" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f22eb0e3c593294a99e9ff4b24cf6b752d43f193aa4415fe5077c159996d497" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "percentage" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd23b938276f14057220b707937bcb42fa76dda7560e57a2da30cb52d557937" +dependencies = [ + "num", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "116bee8279d783c0cf370efa1a94632f2108e5ef0bb32df31f051647810a4e2c" +dependencies = [ + "der 0.4.5", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "pkcs8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" +dependencies = [ + "der 0.4.5", + "pem-rfc7468", + "pkcs1", + "spki 0.4.1", + "zeroize", +] + +[[package]] +name = "pkcs8" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +dependencies = [ + "der 0.5.1", + "spki 0.5.4", + "zeroize", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f32154ba0af3a075eefa1eda8bb414ee928f62303a54ea85b8d6638ff1a6ee9e" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +dependencies = [ + "diff", + "yansi", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid 0.1.0", +] + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "qstring" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "quinn" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e8b432585672228923edbbf64b8b12c14e1112f62e88737655b4a083dbcd78e" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls 0.20.9", + "thiserror", + "tokio", + "tracing", + "webpki", +] + +[[package]] +name = "quinn-proto" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863" +dependencies = [ + "bytes", + "rand 0.8.5", + "ring 0.16.20", + "rustc-hash", + "rustls 0.20.9", + "rustls-native-certs", + "slab", + "thiserror", + "tinyvec", + "tracing", + "webpki", +] + +[[package]] +name = "quinn-udp" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "641538578b21f5e5c8ea733b736895576d0fe329bb883b937db6f4d163dbaaf4" +dependencies = [ + "libc", + "quinn-proto", + "socket2 0.4.9", + "tracing", + "windows-sys 0.42.0", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + +[[package]] +name = "quote" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +dependencies = [ + "proc-macro2 1.0.69", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.10", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rayon" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "rcgen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" +dependencies = [ + "pem", + "ring 0.16.20", + "time", + "yasna", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom 0.2.10", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" + +[[package]] +name = "rend" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "async-compression", + "base64 0.21.5", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.7", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls 0.24.1", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.25.2", + "winreg", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +dependencies = [ + "cc", + "getrandom 0.2.10", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "rkyv" +version = "0.7.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" +dependencies = [ + "bitvec", + "bytecheck", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "rpassword" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322" +dependencies = [ + "libc", + "rtoolbox", + "winapi", +] + +[[package]] +name = "rsa" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c2603e2823634ab331437001b411b9ed11660fbc4066f3908c84a9439260d" +dependencies = [ + "byteorder", + "digest 0.9.0", + "lazy_static", + "num-bigint-dig", + "num-integer", + "num-iter", + "num-traits", + "pkcs1", + "pkcs8 0.7.6", + "rand 0.8.5", + "subtle", + "zeroize", +] + +[[package]] +name = "rtoolbox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "034e22c514f5c0cb8a10ff341b9b048b5ceb21591f31c8f44c43b960f9b3524a" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "rust_decimal" +version = "1.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a2ab0025103a60ecaaf3abf24db1db240a4e1c15837090d2c32f625ac98abea" +dependencies = [ + "arrayvec 0.7.4", + "borsh 0.10.3", + "byteorder", + "bytes", + "num-traits", + "rand 0.8.5", + "rkyv", + "serde", + "serde_json", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom 7.1.3", +] + +[[package]] +name = "rustix" +version = "0.38.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "172891ebdceb05aa0005f533a6cbfca599ddd7d966f6f5d4d9b2e70478e70399" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustls" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +dependencies = [ + "log", + "ring 0.16.20", + "sct", + "webpki", +] + +[[package]] +name = "rustls" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +dependencies = [ + "log", + "ring 0.16.20", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +dependencies = [ + "base64 0.21.5", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +dependencies = [ + "ring 0.16.20", + "untrusted 0.7.1", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scroll" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring 0.16.20", + "untrusted 0.7.1", +] + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" + +[[package]] +name = "serde" +version = "1.0.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "serde_fmt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_json" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +dependencies = [ + "serde", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" +dependencies = [ + "darling", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "sgx-quote" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1640577af7b81d10db340c4b31006b77972e3918f351eec4e65c389c8b58e21" +dependencies = [ + "nom 5.1.3", +] + +[[package]] +name = "sha-1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "solana-account-decoder" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121e55656c2094950f374247e1303dd09517f1ed49c91bf60bf114760b286eb4" +dependencies = [ + "Inflector", + "base64 0.21.5", + "bincode", + "bs58 0.4.0", + "bv", + "lazy_static", + "serde", + "serde_derive", + "serde_json", + "solana-address-lookup-table-program", + "solana-config-program", + "solana-sdk", + "spl-token 4.0.0", + "spl-token-2022 0.9.0", + "spl-token-metadata-interface", + "thiserror", + "zstd", +] + +[[package]] +name = "solana-address-lookup-table-program" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ccb31f7f14d5876acd9ec38f5bf6097bfb4b350141d81c7ff2bf684db3ca815" +dependencies = [ + "bincode", + "bytemuck", + "log", + "num-derive 0.3.3", + "num-traits", + "rustc_version", + "serde", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-program", + "solana-program-runtime", + "solana-sdk", + "thiserror", +] + +[[package]] +name = "solana-clap-utils" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47a8150d4ff694d9587496a5976d33e6ebdb16cc61c6338bdfe3b2fc2c7c4986" +dependencies = [ + "chrono", + "clap 2.34.0", + "rpassword", + "solana-perf", + "solana-remote-wallet", + "solana-sdk", + "thiserror", + "tiny-bip39", + "uriparse", + "url", +] + +[[package]] +name = "solana-client" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35d7582847ab4d60652ff640ca574647789461c1630e8c7580ff770738c3d7f4" +dependencies = [ + "async-trait", + "bincode", + "futures", + "futures-util", + "indexmap", + "indicatif", + "log", + "quinn", + "rand 0.7.3", + "rayon", + "solana-connection-cache", + "solana-measure", + "solana-metrics", + "solana-pubsub-client", + "solana-quic-client", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-rpc-client-nonce-utils", + "solana-sdk", + "solana-streamer", + "solana-thin-client", + "solana-tpu-client", + "solana-udp-client", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-config-program" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94dc0f4463daf1c6155f20eac948ea4ced705e5f5520546aef4e11e746a6d95d" +dependencies = [ + "bincode", + "chrono", + "serde", + "serde_derive", + "solana-program-runtime", + "solana-sdk", +] + +[[package]] +name = "solana-connection-cache" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "758587d44e05a4abdf82b9514d1c8b7d35637ad65f7af7c3e3e02417aaae3c9e" +dependencies = [ + "async-trait", + "bincode", + "futures-util", + "indexmap", + "log", + "rand 0.7.3", + "rayon", + "rcgen", + "solana-measure", + "solana-metrics", + "solana-sdk", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-frozen-abi" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d266bf0311bb403d31206aa2904b8741f57c7f5e27580b6810ad5e22fc7c3282" +dependencies = [ + "ahash 0.8.3", + "blake3", + "block-buffer 0.10.4", + "bs58 0.4.0", + "bv", + "byteorder", + "cc", + "either", + "generic-array", + "getrandom 0.1.16", + "im", + "lazy_static", + "log", + "memmap2", + "once_cell", + "rand_core 0.6.4", + "rustc_version", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "sha2 0.10.7", + "solana-frozen-abi-macro", + "subtle", + "thiserror", +] + +[[package]] +name = "solana-frozen-abi-macro" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dfe18c5155015dcb494c6de84a03b725fcf90ec2006a047769018b94c2cf0de" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "rustc_version", + "syn 2.0.28", +] + +[[package]] +name = "solana-logger" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f76fe25c2d06dcf621befd1e8d5655143e8a059c7e20fcb71736bc80ed779d6" +dependencies = [ + "env_logger 0.9.3", + "lazy_static", + "log", +] + +[[package]] +name = "solana-measure" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db165b8a7f5d840abef011c78a18ffe63cad9192d676b07d94f469b6b5dc6cf6" +dependencies = [ + "log", + "solana-sdk", +] + +[[package]] +name = "solana-metrics" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa01731bb3952904962d49a1ea1205db54e93f3a56f4006d32e02a7c85d60546" +dependencies = [ + "crossbeam-channel", + "gethostname", + "lazy_static", + "log", + "reqwest", + "solana-sdk", +] + +[[package]] +name = "solana-net-utils" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd7ab67329dcebe4a40673fd0da27373282b1359ec7945e0fb81a9c594bcd057" +dependencies = [ + "bincode", + "clap 3.2.25", + "crossbeam-channel", + "log", + "nix", + "rand 0.7.3", + "serde", + "serde_derive", + "socket2 0.4.9", + "solana-logger", + "solana-sdk", + "solana-version", + "tokio", + "url", +] + +[[package]] +name = "solana-perf" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f900c1015844087cd4f10ba9d2d26a9859f2f5ca07427865cc74942595abc0a7" +dependencies = [ + "ahash 0.8.3", + "bincode", + "bv", + "caps", + "curve25519-dalek", + "dlopen", + "dlopen_derive", + "fnv", + "lazy_static", + "libc", + "log", + "nix", + "rand 0.7.3", + "rayon", + "serde", + "solana-metrics", + "solana-rayon-threadlimit", + "solana-sdk", + "solana-vote-program", +] + +[[package]] +name = "solana-program" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bb16998986492de307eef503ce47e84503d35baa92dc60832b22476948b1c16" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "array-bytes", + "base64 0.21.5", + "bincode", + "bitflags 1.3.2", + "blake3", + "borsh 0.10.3", + "borsh 0.9.3", + "bs58 0.4.0", + "bv", + "bytemuck", + "cc", + "console_error_panic_hook", + "console_log", + "curve25519-dalek", + "getrandom 0.2.10", + "itertools", + "js-sys", + "lazy_static", + "libc", + "libsecp256k1", + "log", + "memoffset 0.9.0", + "num-bigint 0.4.4", + "num-derive 0.3.3", + "num-traits", + "parking_lot", + "rand 0.7.3", + "rand_chacha 0.2.2", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "sha2 0.10.7", + "sha3 0.10.8", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk-macro", + "thiserror", + "tiny-bip39", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "solana-program-runtime" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "036d6ecf67a3a7c6dc74d4f7fa6ab321e7ce8feccb7c9dff8384a41d0a12345b" +dependencies = [ + "base64 0.21.5", + "bincode", + "eager", + "enum-iterator", + "itertools", + "libc", + "log", + "num-derive 0.3.3", + "num-traits", + "percentage", + "rand 0.7.3", + "rustc_version", + "serde", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-measure", + "solana-metrics", + "solana-sdk", + "solana_rbpf", + "thiserror", +] + +[[package]] +name = "solana-pubsub-client" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e318f46bedb39374e98f299266a155b2c81c9d920f3c90f761261267c275c1" +dependencies = [ + "crossbeam-channel", + "futures-util", + "log", + "reqwest", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-rpc-client-api", + "solana-sdk", + "thiserror", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite", + "url", +] + +[[package]] +name = "solana-quic-client" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61db18a804642f8eb37369e903774a85d7949a55bd204ec090ebe0742fd2fe32" +dependencies = [ + "async-mutex", + "async-trait", + "futures", + "itertools", + "lazy_static", + "log", + "quinn", + "quinn-proto", + "quinn-udp", + "rcgen", + "rustls 0.20.9", + "solana-connection-cache", + "solana-measure", + "solana-metrics", + "solana-net-utils", + "solana-rpc-client-api", + "solana-sdk", + "solana-streamer", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-rayon-threadlimit" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "805377478f2d413f6cfcba6924c81ac4988ac0f96cdb045a8a9d81c430e6622a" +dependencies = [ + "lazy_static", + "num_cpus", +] + +[[package]] +name = "solana-remote-wallet" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a1148dcd76f76ad0399c1d9abf05cb32a0e545c5bee47ebe6d3b3e800c7fa7c" +dependencies = [ + "console", + "dialoguer", + "log", + "num-derive 0.3.3", + "num-traits", + "parking_lot", + "qstring", + "semver", + "solana-sdk", + "thiserror", + "uriparse", +] + +[[package]] +name = "solana-rpc-client" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc51a85c6ff03bb4a3e1fde1e36dcb553b990f2b3e66aed941a31a6a7c20fa33" +dependencies = [ + "async-trait", + "base64 0.21.5", + "bincode", + "bs58 0.4.0", + "indicatif", + "log", + "reqwest", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-rpc-client-api", + "solana-sdk", + "solana-transaction-status", + "solana-version", + "solana-vote-program", + "tokio", +] + +[[package]] +name = "solana-rpc-client-api" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6756a1f89f509154644a958869c7cc6c70cc622f44faddf9b94612d8d2d8eed5" +dependencies = [ + "base64 0.21.5", + "bs58 0.4.0", + "jsonrpc-core", + "reqwest", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-sdk", + "solana-transaction-status", + "solana-version", + "spl-token-2022 0.9.0", + "thiserror", +] + +[[package]] +name = "solana-rpc-client-nonce-utils" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4850e8db607525a36d330f073703e78e908a54ac66aa323a44cfc12c14c16699" +dependencies = [ + "clap 2.34.0", + "solana-clap-utils", + "solana-rpc-client", + "solana-sdk", + "thiserror", +] + +[[package]] +name = "solana-sdk" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4106cda3d10833ba957dbd25fb841b50aeca7480ccf8f54859294716f54bcd4b" +dependencies = [ + "assert_matches", + "base64 0.21.5", + "bincode", + "bitflags 1.3.2", + "borsh 0.10.3", + "bs58 0.4.0", + "bytemuck", + "byteorder", + "chrono", + "derivation-path", + "digest 0.10.7", + "ed25519-dalek", + "ed25519-dalek-bip32", + "generic-array", + "hmac 0.12.1", + "itertools", + "js-sys", + "lazy_static", + "libsecp256k1", + "log", + "memmap2", + "num-derive 0.3.3", + "num-traits", + "num_enum 0.6.1", + "pbkdf2 0.11.0", + "qstring", + "rand 0.7.3", + "rand_chacha 0.2.2", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "serde_with", + "sha2 0.10.7", + "sha3 0.10.8", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-logger", + "solana-program", + "solana-sdk-macro", + "thiserror", + "uriparse", + "wasm-bindgen", +] + +[[package]] +name = "solana-sdk-macro" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e560806a3859717eb2220b26e2cd68bb757b63affa3e79c3f1d8d853b5ee78f" +dependencies = [ + "bs58 0.4.0", + "proc-macro2 1.0.69", + "quote 1.0.32", + "rustversion", + "syn 2.0.28", +] + +[[package]] +name = "solana-streamer" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78f142cbb497d257e70253c158a4c34037e310d24a055fae7dbc5c396b7611aa" +dependencies = [ + "async-channel", + "bytes", + "crossbeam-channel", + "futures-util", + "histogram", + "indexmap", + "itertools", + "libc", + "log", + "nix", + "pem", + "percentage", + "pkcs8 0.8.0", + "quinn", + "quinn-proto", + "quinn-udp", + "rand 0.7.3", + "rcgen", + "rustls 0.20.9", + "solana-metrics", + "solana-perf", + "solana-sdk", + "thiserror", + "tokio", + "x509-parser", +] + +[[package]] +name = "solana-thin-client" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0e41ce715b34749d2c0d3181dd910d2b99fa2142a0aaf3cd44926cb02edd60d" +dependencies = [ + "bincode", + "log", + "rayon", + "solana-connection-cache", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-sdk", +] + +[[package]] +name = "solana-tpu-client" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84ec99361a39e17a2bffe2a59b97b3d20ddef323f9166929783ce49f340c200d" +dependencies = [ + "async-trait", + "bincode", + "futures-util", + "indexmap", + "indicatif", + "log", + "rand 0.7.3", + "rayon", + "solana-connection-cache", + "solana-measure", + "solana-metrics", + "solana-pubsub-client", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-sdk", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-transaction-status" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "236dd4e43b8a7402bce250228e04c0c68d9493a3e19c71b377ccc7c4390fd969" +dependencies = [ + "Inflector", + "base64 0.21.5", + "bincode", + "borsh 0.10.3", + "bs58 0.4.0", + "lazy_static", + "log", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-address-lookup-table-program", + "solana-sdk", + "spl-associated-token-account 2.2.0", + "spl-memo 4.0.0", + "spl-token 4.0.0", + "spl-token-2022 0.9.0", + "thiserror", +] + +[[package]] +name = "solana-udp-client" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b438036719e5c1201aba2336a5dc1caa8c8eefafd7110b7a3818ae199b54da" +dependencies = [ + "async-trait", + "solana-connection-cache", + "solana-net-utils", + "solana-sdk", + "solana-streamer", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-version" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62847d7ef409e3b410f65e726bf7816d8f8d0330918e78537e940bdf1ca061ae" +dependencies = [ + "log", + "rustc_version", + "semver", + "serde", + "serde_derive", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk", +] + +[[package]] +name = "solana-vote-program" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0c3e5ee7bd03b249c6b80eead5620af62bc7ef1af8ea4f499b8054b00e9c7d" +dependencies = [ + "bincode", + "log", + "num-derive 0.3.3", + "num-traits", + "rustc_version", + "serde", + "serde_derive", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-metrics", + "solana-program", + "solana-program-runtime", + "solana-sdk", + "thiserror", +] + +[[package]] +name = "solana-zk-token-sdk" +version = "1.16.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "278c08e13bc04b6940997602909052524a375154b00cf0bfa934359a3bb7e6f0" +dependencies = [ + "aes-gcm-siv", + "base64 0.21.5", + "bincode", + "bytemuck", + "byteorder", + "curve25519-dalek", + "getrandom 0.1.16", + "itertools", + "lazy_static", + "merlin", + "num-derive 0.3.3", + "num-traits", + "rand 0.7.3", + "serde", + "serde_json", + "sha3 0.9.1", + "solana-program", + "solana-sdk", + "subtle", + "thiserror", + "zeroize", +] + +[[package]] +name = "solana_rbpf" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17d4ba1e58947346e360fabde0697029d36ba83c42f669199b16a8931313cf29" +dependencies = [ + "byteorder", + "combine", + "goblin", + "hash32", + "libc", + "log", + "rand 0.8.5", + "rustc-demangle", + "scroll", + "thiserror", + "winapi", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" +dependencies = [ + "der 0.4.5", +] + +[[package]] +name = "spki" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +dependencies = [ + "base64ct", + "der 0.5.1", +] + +[[package]] +name = "spl-associated-token-account" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978dba3bcbe88d0c2c58366c254d9ea41c5f73357e72fc0bdee4d6b5fc99c8f4" +dependencies = [ + "assert_matches", + "borsh 0.9.3", + "num-derive 0.3.3", + "num-traits", + "solana-program", + "spl-token 3.5.0", + "spl-token-2022 0.6.1", + "thiserror", +] + +[[package]] +name = "spl-associated-token-account" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385e31c29981488f2820b2022d8e731aae3b02e6e18e2fd854e4c9a94dc44fc3" +dependencies = [ + "assert_matches", + "borsh 0.10.3", + "num-derive 0.4.1", + "num-traits", + "solana-program", + "spl-token 4.0.0", + "spl-token-2022 0.9.0", + "thiserror", +] + +[[package]] +name = "spl-discriminator" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cce5d563b58ef1bb2cdbbfe0dfb9ffdc24903b10ae6a4df2d8f425ece375033f" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator-derive", +] + +[[package]] +name = "spl-discriminator-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fadbefec4f3c678215ca72bd71862697bb06b41fd77c0088902dd3203354387b" +dependencies = [ + "quote 1.0.32", + "spl-discriminator-syn", + "syn 2.0.28", +] + +[[package]] +name = "spl-discriminator-syn" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e5f2044ca42c8938d54d1255ce599c79a1ffd86b677dfab695caa20f9ffc3f2" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "sha2 0.10.7", + "syn 2.0.28", + "thiserror", +] + +[[package]] +name = "spl-memo" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0dc6f70db6bacea7ff25870b016a65ba1d1b6013536f08e4fd79a8f9005325" +dependencies = [ + "solana-program", +] + +[[package]] +name = "spl-memo" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f180b03318c3dbab3ef4e1e4d46d5211ae3c780940dd0a28695aba4b59a75a" +dependencies = [ + "solana-program", +] + +[[package]] +name = "spl-pod" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2881dddfca792737c0706fa0175345ab282b1b0879c7d877bad129645737c079" +dependencies = [ + "borsh 0.10.3", + "bytemuck", + "solana-program", + "solana-zk-token-sdk", + "spl-program-error", +] + +[[package]] +name = "spl-program-error" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "249e0318493b6bcf27ae9902600566c689b7dfba9f1bdff5893e92253374e78c" +dependencies = [ + "num-derive 0.4.1", + "num-traits", + "solana-program", + "spl-program-error-derive", + "thiserror", +] + +[[package]] +name = "spl-program-error-derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5269c8e868da17b6552ef35a51355a017bd8e0eae269c201fef830d35fa52c" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "sha2 0.10.7", + "syn 2.0.28", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062e148d3eab7b165582757453632ffeef490c02c86a48bfdb4988f63eefb3b9" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-token" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e85e168a785e82564160dcb87b2a8e04cee9bfd1f4d488c729d53d6a4bd300d" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.3.3", + "num-traits", + "num_enum 0.5.11", + "solana-program", + "thiserror", +] + +[[package]] +name = "spl-token" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08459ba1b8f7c1020b4582c4edf0f5c7511a5e099a7a97570c9698d4f2337060" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.3.3", + "num-traits", + "num_enum 0.6.1", + "solana-program", + "thiserror", +] + +[[package]] +name = "spl-token-2022" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0043b590232c400bad5ee9eb983ced003d15163c4c5d56b090ac6d9a57457b47" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.3.3", + "num-traits", + "num_enum 0.5.11", + "solana-program", + "solana-zk-token-sdk", + "spl-memo 3.0.1", + "spl-token 3.5.0", + "thiserror", +] + +[[package]] +name = "spl-token-2022" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4abf34a65ba420584a0c35f3903f8d727d1f13ababbdc3f714c6b065a686e86" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.1", + "num-traits", + "num_enum 0.7.0", + "solana-program", + "solana-zk-token-sdk", + "spl-memo 4.0.0", + "spl-pod", + "spl-token 4.0.0", + "spl-token-metadata-interface", + "spl-transfer-hook-interface", + "spl-type-length-value", + "thiserror", +] + +[[package]] +name = "spl-token-metadata-interface" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" +dependencies = [ + "borsh 0.10.3", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051d31803f873cabe71aec3c1b849f35248beae5d19a347d93a5c9cccc5d5a9b" +dependencies = [ + "arrayref", + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value", +] + +[[package]] +name = "spl-type-length-value" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a468e6f6371f9c69aae760186ea9f1a01c2908351b06a5e0026d21cfc4d7ecac" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "superslice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" + +[[package]] +name = "sval" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15df12a8db7c216a04b4b438f90d50d5335cd38f161b56389c9f5c9d96d0873" + +[[package]] +name = "sval_buffer" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e80556bc8acea0446e574ce542ad6114a76a0237f28a842bc01ca3ea98f479" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d93d2259edb1d7b4316179f0a98c62e3ffc726f47ab200e07cfe382771f57b8" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532f7f882226f7a5a4656f5151224aaebf8217e0d539cb1595b831bace921343" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e03bd8aa0ae6ee018f7ae95c9714577687a4415bd1a5f19b26e34695f7e072" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_ref" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75ed054f2fb8c2a0ab5d36c1ec57b412919700099fc5e32ad8e7a38b23e1a9e1" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff191c4ff05b67e3844c161021427646cde5d6624597958be158357d9200586" +dependencies = [ + "serde", + "sval", + "sval_buffer", + "sval_fmt", +] + +[[package]] +name = "switchboard-common" +version = "0.11.0" +dependencies = [ + "async-trait", + "base64 0.21.5", + "envy", + "futures", + "getrandom 0.2.10", + "hex", + "ipfs-api-backend-hyper", + "ipfs-api-prelude", + "log", + "serde", + "serde_json", + "sgx-quote", + "sha2 0.10.7", + "sha3 0.10.8", +] + +[[package]] +name = "switchboard-solana" +version = "0.28.70" +dependencies = [ + "anchor-client", + "anchor-lang", + "anchor-spl", + "base64 0.21.5", + "bincode", + "bytemuck", + "chrono", + "cron", + "dashmap", + "futures", + "hex", + "json_env_logger", + "kv-log-macro", + "log", + "pretty_assertions", + "rand 0.8.5", + "reqwest", + "rsa", + "rust_decimal", + "serde", + "serde_json", + "sgx-quote", + "sha2 0.10.7", + "solana-account-decoder", + "solana-address-lookup-table-program", + "solana-client", + "solana-program", + "superslice", + "switchboard-common", + "switchboard-solana-macros", + "tokio", + "url", +] + +[[package]] +name = "switchboard-solana-macros" +version = "0.2.1" +dependencies = [ + "dotenvy", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid 0.1.0", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", + "unicode-xid 0.2.4", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" + +[[package]] +name = "thiserror" +version = "1.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "time" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" +dependencies = [ + "deranged", + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" +dependencies = [ + "time-core", +] + +[[package]] +name = "tiny-bip39" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" +dependencies = [ + "anyhow", + "hmac 0.8.1", + "once_cell", + "pbkdf2 0.4.0", + "rand 0.7.3", + "rustc-hash", + "sha2 0.9.9", + "thiserror", + "unicode-normalization", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.4", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.9", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.7", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" +dependencies = [ + "futures-util", + "log", + "rustls 0.20.9", + "tokio", + "tokio-rustls 0.23.4", + "tungstenite", + "webpki", + "webpki-roots 0.22.6", +] + +[[package]] +name = "tokio-util" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f988a1a1adc2fb21f9c12aa96441da33a1728193ae0b95d2be22dbd17fcb4e5c" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "tungstenite" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" +dependencies = [ + "base64 0.13.1", + "byteorder", + "bytes", + "http", + "httparse", + "log", + "rand 0.8.5", + "rustls 0.20.9", + "sha-1", + "thiserror", + "url", + "utf-8", + "webpki", + "webpki-roots 0.22.6", +] + +[[package]] +name = "typed-builder" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] + +[[package]] +name = "unsigned-varint" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "uriparse" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" +dependencies = [ + "fnv", + "lazy_static", +] + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "uuid" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" + +[[package]] +name = "value-bag" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a72e1902dde2bd6441347de2b70b7f5d59bf157c6c62f0c44572607a1d55bbe" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ba39dc791ecb35baad371a3fc04c6eab688c04937d2e0ac6c22b612c0357bf" +dependencies = [ + "erased-serde", + "serde", + "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e06c10810a57bbf45778d023d432a50a1daa7d185991ae06bcfb6c654d0945" +dependencies = [ + "sval", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote 1.0.32", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring 0.17.5", + "untrusted 0.9.0", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] + +[[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.1", +] + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.1", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x509-parser" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" +dependencies = [ + "asn1-rs", + "base64 0.13.1", + "data-encoding", + "der-parser", + "lazy_static", + "nom 7.1.3", + "oid-registry", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + +[[package]] +name = "zeroize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.8+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" +dependencies = [ + "cc", + "libc", + "pkg-config", +] diff --git a/rust/switchboard-solana/Cargo.anchor28.toml b/rust/switchboard-solana/Cargo.anchor28.toml new file mode 100644 index 000000000..c7a9a81c8 --- /dev/null +++ b/rust/switchboard-solana/Cargo.anchor28.toml @@ -0,0 +1,76 @@ +[package] +name = "switchboard-solana" +version = "0.28.70" +edition = "2021" +resolver = "2" +description = "A Rust library to interact with Switchboard accounts." +readme = "README.md" +keywords = ["switchboard", "oracle", "solana"] +homepage = "https://switchboard.xyz" +repository = "https://github.com/switchboard-xyz/solana-sdk/tree/main/rust/switchboard-solana" +license = "MIT" + +[lib] +crate-type = ["cdylib", "lib"] +name = "switchboard_solana" +doctest = false + +[features] +default = ["cpi"] +no-entrypoint = [] +cpi = ["no-entrypoint"] +secrets = ["rand", "rsa", "reqwest"] +macros = ["switchboard-solana-macros"] +ipfs = ["switchboard-common/ipfs"] +all = ["secrets", "macros", "ipfs"] + +[dependencies] +anchor-spl = "0.28.0" +solana-program = ">= 1.16, < 1.17" +solana-address-lookup-table-program = ">= 1.16, < 1.17" +rust_decimal = "^1" +bytemuck = "^1" +superslice = "1" +log = { version = "0.4", features = ["kv_unstable", "kv_unstable_std"] } +kv-log-macro = "1.0" +switchboard-solana-macros = { version = "0.2.1", path = "../switchboard-solana-macros", optional = true, features = [ + "dotenv", +] } + +[target.'cfg(target_os = "solana")'.dependencies] +switchboard-common = { version = "0.11.0", path = "../switchboard-common" } +anchor-lang = { version = "0.28.0" } + +[target.'cfg(not(target_os = "solana"))'.dependencies] +switchboard-common = { version = "0.11.0", features = [ + "client", +], path = "../switchboard-common" } +anchor-client = { version = "0.28.0" } +solana-client = ">= 1.16, < 1.17" +solana-account-decoder = ">= 1.16, < 1.17" +base64 = "0.21.4" +bincode = { version = "^1" } +sgx-quote = { version = "0.1.0" } +cron = { version = "0.12.0" } +chrono = { version = "0.4.25" } +futures = "0.3" +hex = "0.4.3" +tokio = "1" +url = "2.4" +serde = { version = "^1", features = ["derive"] } +serde_json = { version = "^1" } +sha2 = "0.10.6" +dashmap = "5.5.3" + +# Secrets Dependencies +rsa = { version = "0.5.0", optional = true } +reqwest = { version = "0.11", features = ["json"], optional = true } +rand = { version = "0.8.5", optional = true } + +[package.metadata.docs.rs] +rustdoc-args = ["--cfg", "doc_cfg"] + +[dev-dependencies] +json_env_logger = "0.1" +tokio = { version = "1", features = ["full"] } +pretty_assertions = "1.4.0" diff --git a/rust/switchboard-solana/Cargo.lock b/rust/switchboard-solana/Cargo.lock index 8245ae1c2..630ab5948 100644 --- a/rust/switchboard-solana/Cargo.lock +++ b/rust/switchboard-solana/Cargo.lock @@ -12,6 +12,15 @@ dependencies = [ "regex", ] +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -103,87 +112,79 @@ dependencies = [ [[package]] name = "anchor-attribute-access-control" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa5be5b72abea167f87c868379ba3c2be356bfca9e6f474fd055fa0f7eeb4f2" +checksum = "e5f619f1d04f53621925ba8a2e633ba5a6081f2ae14758cbb67f38fd823e0a3e" dependencies = [ "anchor-syn", - "anyhow", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", - "regex", "syn 1.0.109", ] [[package]] name = "anchor-attribute-account" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f468970344c7c9f9d03b4da854fd7c54f21305059f53789d0045c1dd803f0018" +checksum = "e7f2a3e1df4685f18d12a943a9f2a7456305401af21a07c9fe076ef9ecd6e400" dependencies = [ "anchor-syn", - "anyhow", "bs58 0.5.0", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", - "rustversion", "syn 1.0.109", ] [[package]] name = "anchor-attribute-constant" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59948e7f9ef8144c2aefb3f32a40c5fce2798baeec765ba038389e82301017ef" +checksum = "9423945cb55627f0b30903288e78baf6f62c6c8ab28fb344b6b25f1ffee3dca7" dependencies = [ "anchor-syn", - "proc-macro2 1.0.66", + "quote 1.0.32", "syn 1.0.109", ] [[package]] name = "anchor-attribute-error" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc753c9d1c7981cb8948cf7e162fb0f64558999c0413058e2d43df1df5448086" +checksum = "93ed12720033cc3c3bf3cfa293349c2275cd5ab99936e33dd4bf283aaad3e241" dependencies = [ "anchor-syn", - "proc-macro2 1.0.66", "quote 1.0.32", "syn 1.0.109", ] [[package]] name = "anchor-attribute-event" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38b4e172ba1b52078f53fdc9f11e3dc0668ad27997838a0aad2d148afac8c97" +checksum = "eef4dc0371eba2d8c8b54794b0b0eb786a234a559b77593d6f80825b6d2c77a2" dependencies = [ "anchor-syn", - "anyhow", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", ] [[package]] name = "anchor-attribute-program" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eebd21543606ab61e2d83d9da37d24d3886a49f390f9c43a1964735e8c0f0d5" +checksum = "b18c4f191331e078d4a6a080954d1576241c29c56638783322a18d308ab27e4f" dependencies = [ "anchor-syn", - "anyhow", - "proc-macro2 1.0.66", "quote 1.0.32", "syn 1.0.109", ] [[package]] name = "anchor-client" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8434a6bf33efba0c93157f7fa2fafac658cb26ab75396886dcedd87c2a8ad445" +checksum = "cb48c4a7911038da546dc752655a29fa49f6bd50ebc1edca218bac8da1012acd" dependencies = [ "anchor-lang", "anyhow", @@ -200,33 +201,44 @@ dependencies = [ [[package]] name = "anchor-derive-accounts" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec4720d899b3686396cced9508f23dab420f1308344456ec78ef76f98fda42af" +checksum = "5de10d6e9620d3bcea56c56151cad83c5992f50d5960b3a9bebc4a50390ddc3c" dependencies = [ "anchor-syn", - "anyhow", - "proc-macro2 1.0.66", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-serde" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e2e5be518ec6053d90a2a7f26843dbee607583c779e6c8395951b9739bdfbe" +dependencies = [ + "anchor-syn", + "borsh-derive-internal 0.10.3", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", ] [[package]] name = "anchor-derive-space" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f495e85480bd96ddeb77b71d499247c7d4e8b501e75ecb234e9ef7ae7bd6552a" +checksum = "1ecc31d19fa54840e74b7a979d44bcea49d70459de846088a1d71e87ba53c419" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", ] [[package]] name = "anchor-lang" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d2d4b20100f1310a774aba3471ef268e5c4ba4d5c28c0bbe663c2658acbc414" +checksum = "35da4785497388af0553586d55ebdc08054a8b1724720ef2749d313494f2b8ad" dependencies = [ "anchor-attribute-access-control", "anchor-attribute-account", @@ -235,6 +247,7 @@ dependencies = [ "anchor-attribute-event", "anchor-attribute-program", "anchor-derive-accounts", + "anchor-derive-serde", "anchor-derive-space", "arrayref", "base64 0.13.1", @@ -248,9 +261,9 @@ dependencies = [ [[package]] name = "anchor-spl" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78f860599da1c2354e7234c768783049eb42e2f54509ecfc942d2e0076a2da7b" +checksum = "6c4fd6e43b2ca6220d2ef1641539e678bfc31b6cc393cf892b373b5997b6a39a" dependencies = [ "anchor-lang", "solana-program", @@ -261,14 +274,14 @@ dependencies = [ [[package]] name = "anchor-syn" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a125e4b0cc046cfec58f5aa25038e34cf440151d58f0db3afc55308251fe936d" +checksum = "d9101b84702fed2ea57bd22992f75065da5648017135b844283a2f6d74f27825" dependencies = [ "anyhow", "bs58 0.5.0", "heck", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "serde", "serde_json", @@ -348,7 +361,7 @@ dependencies = [ "derivative", "digest 0.10.7", "itertools", - "num-bigint 0.4.3", + "num-bigint 0.4.4", "num-traits", "paste", "rustc_version", @@ -371,9 +384,9 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ - "num-bigint 0.4.3", + "num-bigint 0.4.4", "num-traits", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", ] @@ -400,7 +413,7 @@ dependencies = [ "ark-serialize-derive", "ark-std", "digest 0.10.7", - "num-bigint 0.4.3", + "num-bigint 0.4.4", ] [[package]] @@ -409,7 +422,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", ] @@ -467,7 +480,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.25", + "time", ] [[package]] @@ -476,7 +489,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", "synstructure", @@ -488,7 +501,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", ] @@ -512,9 +525,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.3.15" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a" +checksum = "f658e2baef915ba0f26f1f7c42bfb8e12f532a01f449a090ded75ae7a07e9ba2" dependencies = [ "brotli", "flate2", @@ -535,11 +548,11 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.72" +version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 2.0.28", ] @@ -561,6 +574,27 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + [[package]] name = "base64" version = "0.12.3" @@ -575,9 +609,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" @@ -629,9 +663,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5" +checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" dependencies = [ "arrayref", "arrayvec 0.7.4", @@ -695,7 +729,7 @@ dependencies = [ "borsh-derive-internal 0.9.3", "borsh-schema-derive-internal 0.9.3", "proc-macro-crate 0.1.5", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "syn 1.0.109", ] @@ -708,7 +742,7 @@ dependencies = [ "borsh-derive-internal 0.10.3", "borsh-schema-derive-internal 0.10.3", "proc-macro-crate 0.1.5", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "syn 1.0.109", ] @@ -718,7 +752,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", ] @@ -729,7 +763,7 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", ] @@ -740,7 +774,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", ] @@ -751,7 +785,7 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", ] @@ -825,16 +859,16 @@ version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", ] [[package]] name = "bytemuck" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" dependencies = [ "bytemuck_derive", ] @@ -845,7 +879,7 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 2.0.28", ] @@ -858,9 +892,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "caps" @@ -874,9 +908,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", "libc", @@ -890,18 +924,17 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", - "time 0.1.45", "wasm-bindgen", - "winapi", + "windows-targets 0.48.1", ] [[package]] @@ -937,7 +970,7 @@ dependencies = [ "atty", "bitflags 1.3.2", "clap_lex", - "indexmap 1.9.3", + "indexmap", "once_cell", "strsim 0.10.0", "termcolor", @@ -966,6 +999,22 @@ dependencies = [ "unreachable", ] +[[package]] +name = "common-multipart-rfc7578" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baee326bc603965b0f26583e1ecd7c111c41b49bd92a344897476a352798869" +dependencies = [ + "bytes", + "futures-core", + "futures-util", + "http", + "mime", + "mime_guess", + "rand 0.8.5", + "thiserror", +] + [[package]] name = "concurrent-queue" version = "2.2.0" @@ -1042,6 +1091,15 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + [[package]] name = "cpufeatures" version = "0.2.9" @@ -1192,7 +1250,7 @@ checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "strsim 0.10.0", "syn 2.0.28", @@ -1209,12 +1267,45 @@ dependencies = [ "syn 2.0.28", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.1", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +[[package]] +name = "data-encoding-macro" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" +dependencies = [ + "data-encoding", + "syn 1.0.109", +] + [[package]] name = "der" version = "0.4.5" @@ -1243,7 +1334,7 @@ dependencies = [ "asn1-rs", "displaydoc", "nom 7.1.3", - "num-bigint 0.4.3", + "num-bigint 0.4.4", "num-traits", "rusticata-macros", ] @@ -1266,7 +1357,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", ] @@ -1283,6 +1374,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "digest" version = "0.9.0" @@ -1303,13 +1400,33 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "displaydoc" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 2.0.28", ] @@ -1337,6 +1454,12 @@ dependencies = [ "syn 0.15.44", ] +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + [[package]] name = "eager" version = "0.1.0" @@ -1414,11 +1537,20 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 2.0.28", ] +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "log", +] + [[package]] name = "env_logger" version = "0.9.3" @@ -1442,10 +1574,13 @@ dependencies = [ ] [[package]] -name = "equivalent" -version = "1.0.1" +name = "erased-serde" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +dependencies = [ + "serde", +] [[package]] name = "errno" @@ -1586,7 +1721,7 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 2.0.28", ] @@ -1668,6 +1803,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + [[package]] name = "goblin" version = "0.5.4" @@ -1691,7 +1832,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap", "slab", "tokio", "tokio-util", @@ -1736,9 +1877,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" [[package]] name = "heck" @@ -1866,24 +2007,38 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", "want", ] +[[package]] +name = "hyper-multipart-rfc7578" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb2cf73e96e9925f4bed948e763aa2901c2f1a3a5f713ee41917433ced6671" +dependencies = [ + "bytes", + "common-multipart-rfc7578", + "futures-core", + "http", + "hyper", +] + [[package]] name = "hyper-rustls" -version = "0.23.2" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ + "futures-util", "http", "hyper", - "rustls", + "rustls 0.21.7", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", ] [[package]] @@ -1964,21 +2119,11 @@ dependencies = [ "hashbrown 0.12.3", ] -[[package]] -name = "indexmap" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" -dependencies = [ - "equivalent", - "hashbrown 0.14.0", -] - [[package]] name = "indicatif" -version = "0.17.6" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730" +checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" dependencies = [ "console", "instant", @@ -1996,6 +2141,49 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "ipfs-api-backend-hyper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9d131b408b4caafe1e7c00d410a09ad3eb7e3ab68690cf668e86904b2176b4" +dependencies = [ + "async-trait", + "base64 0.13.1", + "bytes", + "futures", + "http", + "hyper", + "hyper-multipart-rfc7578", + "ipfs-api-prelude", + "thiserror", +] + +[[package]] +name = "ipfs-api-prelude" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b74065805db266ba2c6edbd670b23c4714824a955628472b2e46cc9f3a869cb" +dependencies = [ + "async-trait", + "bytes", + "cfg-if", + "common-multipart-rfc7578", + "dirs", + "futures", + "http", + "multiaddr", + "multibase", + "serde", + "serde_json", + "serde_urlencoded", + "thiserror", + "tokio", + "tokio-util", + "tracing", + "typed-builder", + "walkdir", +] + [[package]] name = "ipnet" version = "2.8.0" @@ -2035,6 +2223,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json_env_logger" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e2ec540ea0448b187d3a8b4a9f13e75527d06ef76b3a2baa1cd982aecb62ce2" +dependencies = [ + "env_logger 0.7.1", + "kv-log-macro", + "log", + "serde_json", +] + [[package]] name = "jsonrpc-core" version = "18.0.0" @@ -2059,13 +2259,22 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" dependencies = [ - "spin", + "spin 0.5.2", ] [[package]] @@ -2083,9 +2292,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.147" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libm" @@ -2093,6 +2302,17 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.3.3", + "libc", + "redox_syscall 0.4.1", +] + [[package]] name = "libsecp256k1" version = "0.6.0" @@ -2159,9 +2379,12 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +dependencies = [ + "value-bag", +] [[package]] name = "memchr" @@ -2214,6 +2437,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2231,24 +2464,68 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.14" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "multiaddr" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b36f567c7099511fa8612bbbb52dda2419ce0bdbacf31714e3a5ffdb766d3bd" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", "log", - "miow", - "ntapi", - "winapi", + "multibase", + "multihash", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint", + "url", ] [[package]] -name = "miow" -version = "0.3.7" +name = "multibase" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" dependencies = [ - "winapi", + "base-x", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "multihash" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40" +dependencies = [ + "core2", + "multihash-derive", + "unsigned-varint", +] + +[[package]] +name = "multihash-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro-error", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", + "synstructure", ] [[package]] @@ -2271,16 +2548,15 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", "memoffset 0.7.1", "pin-utils", - "static_assertions", ] [[package]] @@ -2304,15 +2580,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "ntapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" -dependencies = [ - "winapi", -] - [[package]] name = "num" version = "0.2.1" @@ -2340,9 +2607,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", @@ -2382,13 +2649,24 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", ] [[package]] -name = "num-integer" +name = "num-derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + +[[package]] +name = "num-integer" version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" @@ -2442,42 +2720,42 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.11" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" dependencies = [ - "num_enum_derive 0.5.11", + "num_enum_derive 0.6.1", ] [[package]] name = "num_enum" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb" dependencies = [ - "num_enum_derive 0.6.1", + "num_enum_derive 0.7.0", ] [[package]] name = "num_enum_derive" -version = "0.5.11" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2 1.0.66", + "proc-macro-crate 1.1.3", + "proc-macro2 1.0.69", "quote 1.0.32", - "syn 1.0.109", + "syn 2.0.28", ] [[package]] name = "num_enum_derive" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597" dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2 1.0.66", + "proc-macro-crate 1.1.3", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 2.0.28", ] @@ -2488,6 +2766,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + [[package]] name = "oid-registry" version = "0.6.1" @@ -2530,7 +2817,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 2.0.28", ] @@ -2559,17 +2846,6 @@ version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -2577,21 +2853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.8", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -2747,6 +3009,16 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +dependencies = [ + "diff", + "yansi", +] + [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -2758,12 +3030,36 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" dependencies = [ - "once_cell", - "toml_edit", + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "version_check", ] [[package]] @@ -2777,9 +3073,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -2799,7 +3095,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", ] @@ -2824,7 +3120,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls", + "rustls 0.20.9", "thiserror", "tokio", "tracing", @@ -2833,15 +3129,15 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.9.4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31999cfc7927c4e212e60fd50934ab40e8e8bfd2d493d6095d2d306bc0764d9" +checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863" dependencies = [ "bytes", "rand 0.8.5", - "ring", + "ring 0.16.20", "rustc-hash", - "rustls", + "rustls 0.20.9", "rustls-native-certs", "slab", "thiserror", @@ -2858,7 +3154,7 @@ checksum = "641538578b21f5e5c8ea733b736895576d0fe329bb883b937db6f4d163dbaaf4" dependencies = [ "libc", "quinn-proto", - "socket2", + "socket2 0.4.9", "tracing", "windows-sys 0.42.0", ] @@ -2878,7 +3174,7 @@ version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", ] [[package]] @@ -2996,29 +3292,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ "pem", - "ring", - "time 0.3.25", + "ring 0.16.20", + "time", "yasna", ] [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom 0.2.10", + "libredox", + "thiserror", +] + [[package]] name = "regex" version = "1.9.3" @@ -3059,12 +3366,12 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.17" +version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ "async-compression", - "base64 0.21.2", + "base64 0.21.5", "bytes", "encoding_rs", "futures-core", @@ -3083,21 +3390,22 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls", + "rustls 0.21.7", "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", + "system-configuration", "tokio", "tokio-native-tls", - "tokio-rustls", + "tokio-rustls 0.24.1", "tokio-util", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", + "webpki-roots 0.25.2", "winreg", ] @@ -3110,12 +3418,26 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", - "untrusted", + "spin 0.5.2", + "untrusted 0.7.1", "web-sys", "winapi", ] +[[package]] +name = "ring" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +dependencies = [ + "cc", + "getrandom 0.2.10", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + [[package]] name = "rkyv" version = "0.7.42" @@ -3139,7 +3461,7 @@ version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", ] @@ -3247,16 +3569,28 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", - "ring", + "ring 0.16.20", "sct", "webpki", ] +[[package]] +name = "rustls" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +dependencies = [ + "log", + "ring 0.16.20", + "rustls-webpki", + "sct", +] + [[package]] name = "rustls-native-certs" version = "0.6.3" @@ -3275,7 +3609,17 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.5", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +dependencies = [ + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -3290,6 +3634,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.22" @@ -3320,7 +3673,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 2.0.28", ] @@ -3331,8 +3684,8 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -3366,15 +3719,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.183" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" +checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" dependencies = [ "serde_derive", ] @@ -3390,20 +3743,29 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.183" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" +checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 2.0.28", ] +[[package]] +name = "serde_fmt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" +dependencies = [ + "serde", +] + [[package]] name = "serde_json" -version = "1.0.104" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -3439,7 +3801,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ "darling", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 2.0.28", ] @@ -3572,14 +3934,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "solana-account-decoder" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298accbe9b2bffc391081b94f30ec3dd5bac053bfcd09aa78c06f1f87d33ec1e" +checksum = "121e55656c2094950f374247e1303dd09517f1ed49c91bf60bf114760b286eb4" dependencies = [ "Inflector", - "base64 0.21.2", + "base64 0.21.5", "bincode", "bs58 0.4.0", "bv", @@ -3592,20 +3964,21 @@ dependencies = [ "solana-sdk", "spl-token", "spl-token-2022", + "spl-token-metadata-interface", "thiserror", "zstd", ] [[package]] name = "solana-address-lookup-table-program" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c026db45d6d8a21afe308fab93a40c77d21cb7a0f1f2fe4b99bb7bbcd7028ed7" +checksum = "3ccb31f7f14d5876acd9ec38f5bf6097bfb4b350141d81c7ff2bf684db3ca815" dependencies = [ "bincode", "bytemuck", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", "rustc_version", "serde", @@ -3619,9 +3992,9 @@ dependencies = [ [[package]] name = "solana-clap-utils" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d27f6ef67bb0519da2d7c7dd9f65c8e447a9a1c8330bb032b78d80712472fefd" +checksum = "47a8150d4ff694d9587496a5976d33e6ebdb16cc61c6338bdfe3b2fc2c7c4986" dependencies = [ "chrono", "clap 2.34.0", @@ -3637,15 +4010,15 @@ dependencies = [ [[package]] name = "solana-client" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13cf67b2f89d8ce5ce0b8c75baac79dc10b082cf096b149146724182db5506cf" +checksum = "35d7582847ab4d60652ff640ca574647789461c1630e8c7580ff770738c3d7f4" dependencies = [ "async-trait", "bincode", "futures", "futures-util", - "indexmap 1.9.3", + "indexmap", "indicatif", "log", "quinn", @@ -3670,9 +4043,9 @@ dependencies = [ [[package]] name = "solana-config-program" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4065170279a38c1013fcf9c1776579914e7c30edb831f28dfd59f9d939d90f63" +checksum = "94dc0f4463daf1c6155f20eac948ea4ced705e5f5520546aef4e11e746a6d95d" dependencies = [ "bincode", "chrono", @@ -3684,14 +4057,14 @@ dependencies = [ [[package]] name = "solana-connection-cache" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a98001f5293720075b52faa7e05c78c33ffdcc23ed7dea2cad102ed4823d624" +checksum = "758587d44e05a4abdf82b9514d1c8b7d35637ad65f7af7c3e3e02417aaae3c9e" dependencies = [ "async-trait", "bincode", "futures-util", - "indexmap 1.9.3", + "indexmap", "log", "rand 0.7.3", "rayon", @@ -3705,9 +4078,9 @@ dependencies = [ [[package]] name = "solana-frozen-abi" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee2b96d4150d9ebf55e903014bc332ac64c642837d7f1e6f7b911d709331380" +checksum = "d266bf0311bb403d31206aa2904b8741f57c7f5e27580b6810ad5e22fc7c3282" dependencies = [ "ahash 0.8.3", "blake3", @@ -3738,11 +4111,11 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942534eb972f955ed186175495654cabece6261a8ac3211e5791440d40a1ed96" +checksum = "6dfe18c5155015dcb494c6de84a03b725fcf90ec2006a047769018b94c2cf0de" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "rustc_version", "syn 2.0.28", @@ -3750,20 +4123,20 @@ dependencies = [ [[package]] name = "solana-logger" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1339e1a179e2465e97fd89c2f70d5f00c5644f36c0e547b8ecda414c748dfc2c" +checksum = "4f76fe25c2d06dcf621befd1e8d5655143e8a059c7e20fcb71736bc80ed779d6" dependencies = [ - "env_logger", + "env_logger 0.9.3", "lazy_static", "log", ] [[package]] name = "solana-measure" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b3feab384868634ea5d7a12fc62c001d5785b6a352b7903ad13edbb7d3043f3" +checksum = "db165b8a7f5d840abef011c78a18ffe63cad9192d676b07d94f469b6b5dc6cf6" dependencies = [ "log", "solana-sdk", @@ -3771,9 +4144,9 @@ dependencies = [ [[package]] name = "solana-metrics" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31c1f2569ea75ee9aa73eedb948b17eabc468e6cd5c1aee4d9cdfaffb0f3d33" +checksum = "aa01731bb3952904962d49a1ea1205db54e93f3a56f4006d32e02a7c85d60546" dependencies = [ "crossbeam-channel", "gethostname", @@ -3785,9 +4158,9 @@ dependencies = [ [[package]] name = "solana-net-utils" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "725a2f7335cc7ec5be356baaf44b0d3211f996b174e2a3b340227e700d26fc55" +checksum = "fd7ab67329dcebe4a40673fd0da27373282b1359ec7945e0fb81a9c594bcd057" dependencies = [ "bincode", "clap 3.2.25", @@ -3797,7 +4170,7 @@ dependencies = [ "rand 0.7.3", "serde", "serde_derive", - "socket2", + "socket2 0.4.9", "solana-logger", "solana-sdk", "solana-version", @@ -3807,9 +4180,9 @@ dependencies = [ [[package]] name = "solana-perf" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2048b4890677ec4287a205a0f53d6a9bf2bdbcc7046aeb665b2714e3c1a4e655" +checksum = "f900c1015844087cd4f10ba9d2d26a9859f2f5ca07427865cc74942595abc0a7" dependencies = [ "ahash 0.8.3", "bincode", @@ -3834,16 +4207,16 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f81c59ed0b65b403cc5db459dd1214dfab89ccd3ce20aadf98102b072d08562" +checksum = "1bb16998986492de307eef503ce47e84503d35baa92dc60832b22476948b1c16" dependencies = [ "ark-bn254", "ark-ec", "ark-ff", "ark-serialize", "array-bytes", - "base64 0.21.2", + "base64 0.21.5", "bincode", "bitflags 1.3.2", "blake3", @@ -3864,10 +4237,10 @@ dependencies = [ "libsecp256k1", "log", "memoffset 0.9.0", - "num-bigint 0.4.3", - "num-derive", + "num-bigint 0.4.4", + "num-derive 0.3.3", "num-traits", - "parking_lot 0.12.1", + "parking_lot", "rand 0.7.3", "rand_chacha 0.2.2", "rustc_version", @@ -3889,18 +4262,18 @@ dependencies = [ [[package]] name = "solana-program-runtime" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc8624325d63e9a643385739c53315d8768aff689dfa9ad06ed1c67aac163ab2" +checksum = "036d6ecf67a3a7c6dc74d4f7fa6ab321e7ce8feccb7c9dff8384a41d0a12345b" dependencies = [ - "base64 0.21.2", + "base64 0.21.5", "bincode", "eager", "enum-iterator", "itertools", "libc", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", "percentage", "rand 0.7.3", @@ -3917,9 +4290,9 @@ dependencies = [ [[package]] name = "solana-pubsub-client" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e10c8caee33c14b74fa2e76f8d8638364303bbf4439e284fddf66b7e3a5acb" +checksum = "70e318f46bedb39374e98f299266a155b2c81c9d920f3c90f761261267c275c1" dependencies = [ "crossbeam-channel", "futures-util", @@ -3942,9 +4315,9 @@ dependencies = [ [[package]] name = "solana-quic-client" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7173c8eb7b20a1c04838655760ba36e5a4398dc9cd16115a5321c7a56e6a34ff" +checksum = "61db18a804642f8eb37369e903774a85d7949a55bd204ec090ebe0742fd2fe32" dependencies = [ "async-mutex", "async-trait", @@ -3956,7 +4329,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rcgen", - "rustls", + "rustls 0.20.9", "solana-connection-cache", "solana-measure", "solana-metrics", @@ -3970,9 +4343,9 @@ dependencies = [ [[package]] name = "solana-rayon-threadlimit" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe5195e62d9457233f97f30aa678f71b1aaed2200a170e63f0da7d9a3d124aa3" +checksum = "805377478f2d413f6cfcba6924c81ac4988ac0f96cdb045a8a9d81c430e6622a" dependencies = [ "lazy_static", "num_cpus", @@ -3980,16 +4353,16 @@ dependencies = [ [[package]] name = "solana-remote-wallet" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04b5777335473d24b6edf9ca36129b1f8e07ba34de18e2b8d6285a4e3473260c" +checksum = "7a1148dcd76f76ad0399c1d9abf05cb32a0e545c5bee47ebe6d3b3e800c7fa7c" dependencies = [ "console", "dialoguer", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", - "parking_lot 0.12.1", + "parking_lot", "qstring", "semver", "solana-sdk", @@ -3999,12 +4372,12 @@ dependencies = [ [[package]] name = "solana-rpc-client" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d34afb705efdf62ad1a911beffe3c6d599eab2125bd07460e85a424636cb54" +checksum = "dc51a85c6ff03bb4a3e1fde1e36dcb553b990f2b3e66aed941a31a6a7c20fa33" dependencies = [ "async-trait", - "base64 0.21.2", + "base64 0.21.5", "bincode", "bs58 0.4.0", "indicatif", @@ -4025,11 +4398,11 @@ dependencies = [ [[package]] name = "solana-rpc-client-api" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e28db9b3748bfe7367ef9e9b968be1643f63ab9c360e89681d426d036cf69a" +checksum = "6756a1f89f509154644a958869c7cc6c70cc622f44faddf9b94612d8d2d8eed5" dependencies = [ - "base64 0.21.2", + "base64 0.21.5", "bs58 0.4.0", "jsonrpc-core", "reqwest", @@ -4047,9 +4420,9 @@ dependencies = [ [[package]] name = "solana-rpc-client-nonce-utils" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27c9c9f034bf3c931441a0fbb528b8e3bf417a32b70546e5fa0c00cd78559ff5" +checksum = "4850e8db607525a36d330f073703e78e908a54ac66aa323a44cfc12c14c16699" dependencies = [ "clap 2.34.0", "solana-clap-utils", @@ -4060,12 +4433,12 @@ dependencies = [ [[package]] name = "solana-sdk" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23dbf6da55a2d191956c693d8490dc809799822536aceb11309043e9b622079" +checksum = "4106cda3d10833ba957dbd25fb841b50aeca7480ccf8f54859294716f54bcd4b" dependencies = [ "assert_matches", - "base64 0.21.2", + "base64 0.21.5", "bincode", "bitflags 1.3.2", "borsh 0.10.3", @@ -4085,7 +4458,7 @@ dependencies = [ "libsecp256k1", "log", "memmap2", - "num-derive", + "num-derive 0.3.3", "num-traits", "num_enum 0.6.1", "pbkdf2 0.11.0", @@ -4113,12 +4486,12 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7d686e405694cd6510cd77bb87d0eeda64ad3df08d3293278ba47ca78b8e5e" +checksum = "1e560806a3859717eb2220b26e2cd68bb757b63affa3e79c3f1d8d853b5ee78f" dependencies = [ "bs58 0.4.0", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "rustversion", "syn 2.0.28", @@ -4126,16 +4499,16 @@ dependencies = [ [[package]] name = "solana-streamer" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e40e74d6ae01dd21dc1a93a2213f8d7e04aea69079092a131ad5bd2d54aa16bc" +checksum = "78f142cbb497d257e70253c158a4c34037e310d24a055fae7dbc5c396b7611aa" dependencies = [ "async-channel", "bytes", "crossbeam-channel", "futures-util", "histogram", - "indexmap 1.9.3", + "indexmap", "itertools", "libc", "log", @@ -4148,7 +4521,7 @@ dependencies = [ "quinn-udp", "rand 0.7.3", "rcgen", - "rustls", + "rustls 0.20.9", "solana-metrics", "solana-perf", "solana-sdk", @@ -4159,9 +4532,9 @@ dependencies = [ [[package]] name = "solana-thin-client" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f3a1dae21f002f2d35ddfcc09fb528bc52936bb9fe4aea7bb46b1361998ed7" +checksum = "e0e41ce715b34749d2c0d3181dd910d2b99fa2142a0aaf3cd44926cb02edd60d" dependencies = [ "bincode", "log", @@ -4174,14 +4547,14 @@ dependencies = [ [[package]] name = "solana-tpu-client" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fffd371a68959dbbbb073198cd93121586da924a8dc493bd624a5ddf40a6742" +checksum = "84ec99361a39e17a2bffe2a59b97b3d20ddef323f9166929783ce49f340c200d" dependencies = [ "async-trait", "bincode", "futures-util", - "indexmap 1.9.3", + "indexmap", "indicatif", "log", "rand 0.7.3", @@ -4199,14 +4572,14 @@ dependencies = [ [[package]] name = "solana-transaction-status" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeb3b1a35fc4718e758851670a959bb4736a8825f56c7ebfcd6eec892cbd200a" +checksum = "236dd4e43b8a7402bce250228e04c0c68d9493a3e19c71b377ccc7c4390fd969" dependencies = [ "Inflector", - "base64 0.21.2", + "base64 0.21.5", "bincode", - "borsh 0.9.3", + "borsh 0.10.3", "bs58 0.4.0", "lazy_static", "log", @@ -4225,9 +4598,9 @@ dependencies = [ [[package]] name = "solana-udp-client" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05fd1c52102c716767d32a6936843b0505ad61bad958b34bcff513fe609611e7" +checksum = "16b438036719e5c1201aba2336a5dc1caa8c8eefafd7110b7a3818ae199b54da" dependencies = [ "async-trait", "solana-connection-cache", @@ -4240,9 +4613,9 @@ dependencies = [ [[package]] name = "solana-version" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4f9750ce47f0a431338121a3247bd29665d6da5a8ebde8c5320503c98d8adc" +checksum = "62847d7ef409e3b410f65e726bf7816d8f8d0330918e78537e940bdf1ca061ae" dependencies = [ "log", "rustc_version", @@ -4256,13 +4629,13 @@ dependencies = [ [[package]] name = "solana-vote-program" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258b4c3e62faaed0cd864b02760659e45fb4431a287ee0088ae79af891ae4786" +checksum = "fb0c3e5ee7bd03b249c6b80eead5620af62bc7ef1af8ea4f499b8054b00e9c7d" dependencies = [ "bincode", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", "rustc_version", "serde", @@ -4278,12 +4651,12 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" -version = "1.16.7" +version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2d04eecf3a7438c95db28b57437e94f09a1e60377183d9bea0c9db84506f504" +checksum = "278c08e13bc04b6940997602909052524a375154b00cf0bfa934359a3bb7e6f0" dependencies = [ "aes-gcm-siv", - "base64 0.21.2", + "base64 0.21.5", "bincode", "bytemuck", "byteorder", @@ -4292,7 +4665,7 @@ dependencies = [ "itertools", "lazy_static", "merlin", - "num-derive", + "num-derive 0.3.3", "num-traits", "rand 0.7.3", "serde", @@ -4307,9 +4680,9 @@ dependencies = [ [[package]] name = "solana_rbpf" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3082ec3a1d4ef7879eb5b84916d5acde057abd59733eec3647e0ab8885283ef" +checksum = "17d4ba1e58947346e360fabde0697029d36ba83c42f669199b16a8931313cf29" dependencies = [ "byteorder", "combine", @@ -4330,6 +4703,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "spki" version = "0.4.1" @@ -4351,13 +4730,13 @@ dependencies = [ [[package]] name = "spl-associated-token-account" -version = "1.1.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978dba3bcbe88d0c2c58366c254d9ea41c5f73357e72fc0bdee4d6b5fc99c8f4" +checksum = "385e31c29981488f2820b2022d8e731aae3b02e6e18e2fd854e4c9a94dc44fc3" dependencies = [ "assert_matches", - "borsh 0.9.3", - "num-derive", + "borsh 0.10.3", + "num-derive 0.4.1", "num-traits", "solana-program", "spl-token", @@ -4365,48 +4744,182 @@ dependencies = [ "thiserror", ] +[[package]] +name = "spl-discriminator" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cce5d563b58ef1bb2cdbbfe0dfb9ffdc24903b10ae6a4df2d8f425ece375033f" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator-derive", +] + +[[package]] +name = "spl-discriminator-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fadbefec4f3c678215ca72bd71862697bb06b41fd77c0088902dd3203354387b" +dependencies = [ + "quote 1.0.32", + "spl-discriminator-syn", + "syn 2.0.28", +] + +[[package]] +name = "spl-discriminator-syn" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e5f2044ca42c8938d54d1255ce599c79a1ffd86b677dfab695caa20f9ffc3f2" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "sha2 0.10.7", + "syn 2.0.28", + "thiserror", +] + [[package]] name = "spl-memo" -version = "3.0.1" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f180b03318c3dbab3ef4e1e4d46d5211ae3c780940dd0a28695aba4b59a75a" +dependencies = [ + "solana-program", +] + +[[package]] +name = "spl-pod" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2881dddfca792737c0706fa0175345ab282b1b0879c7d877bad129645737c079" +dependencies = [ + "borsh 0.10.3", + "bytemuck", + "solana-program", + "solana-zk-token-sdk", + "spl-program-error", +] + +[[package]] +name = "spl-program-error" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0dc6f70db6bacea7ff25870b016a65ba1d1b6013536f08e4fd79a8f9005325" +checksum = "249e0318493b6bcf27ae9902600566c689b7dfba9f1bdff5893e92253374e78c" dependencies = [ + "num-derive 0.4.1", + "num-traits", "solana-program", + "spl-program-error-derive", + "thiserror", +] + +[[package]] +name = "spl-program-error-derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5269c8e868da17b6552ef35a51355a017bd8e0eae269c201fef830d35fa52c" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "sha2 0.10.7", + "syn 2.0.28", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062e148d3eab7b165582757453632ffeef490c02c86a48bfdb4988f63eefb3b9" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", ] [[package]] name = "spl-token" -version = "3.5.0" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e85e168a785e82564160dcb87b2a8e04cee9bfd1f4d488c729d53d6a4bd300d" +checksum = "08459ba1b8f7c1020b4582c4edf0f5c7511a5e099a7a97570c9698d4f2337060" dependencies = [ "arrayref", "bytemuck", - "num-derive", + "num-derive 0.3.3", "num-traits", - "num_enum 0.5.11", + "num_enum 0.6.1", "solana-program", "thiserror", ] [[package]] name = "spl-token-2022" -version = "0.6.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0043b590232c400bad5ee9eb983ced003d15163c4c5d56b090ac6d9a57457b47" +checksum = "e4abf34a65ba420584a0c35f3903f8d727d1f13ababbdc3f714c6b065a686e86" dependencies = [ "arrayref", "bytemuck", - "num-derive", + "num-derive 0.4.1", "num-traits", - "num_enum 0.5.11", + "num_enum 0.7.0", "solana-program", "solana-zk-token-sdk", "spl-memo", + "spl-pod", "spl-token", + "spl-token-metadata-interface", + "spl-transfer-hook-interface", + "spl-type-length-value", "thiserror", ] +[[package]] +name = "spl-token-metadata-interface" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" +dependencies = [ + "borsh 0.10.3", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051d31803f873cabe71aec3c1b849f35248beae5d19a347d93a5c9cccc5d5a9b" +dependencies = [ + "arrayref", + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value", +] + +[[package]] +name = "spl-type-length-value" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a468e6f6371f9c69aae760186ea9f1a01c2908351b06a5e0026d21cfc4d7ecac" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -4437,31 +4950,113 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" +[[package]] +name = "sval" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15df12a8db7c216a04b4b438f90d50d5335cd38f161b56389c9f5c9d96d0873" + +[[package]] +name = "sval_buffer" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e80556bc8acea0446e574ce542ad6114a76a0237f28a842bc01ca3ea98f479" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d93d2259edb1d7b4316179f0a98c62e3ffc726f47ab200e07cfe382771f57b8" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532f7f882226f7a5a4656f5151224aaebf8217e0d539cb1595b831bace921343" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e03bd8aa0ae6ee018f7ae95c9714577687a4415bd1a5f19b26e34695f7e072" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_ref" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75ed054f2fb8c2a0ab5d36c1ec57b412919700099fc5e32ad8e7a38b23e1a9e1" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff191c4ff05b67e3844c161021427646cde5d6624597958be158357d9200586" +dependencies = [ + "serde", + "sval", + "sval_buffer", + "sval_fmt", +] + [[package]] name = "switchboard-common" -version = "0.8.20" +version = "0.11.0" dependencies = [ + "async-trait", + "base64 0.21.5", "envy", + "futures", "getrandom 0.2.10", "hex", + "ipfs-api-backend-hyper", + "ipfs-api-prelude", + "log", "serde", "serde_json", "sgx-quote", "sha2 0.10.7", + "sha3 0.10.8", ] [[package]] name = "switchboard-solana" -version = "0.28.21" +version = "0.29.70" dependencies = [ "anchor-client", "anchor-lang", "anchor-spl", + "base64 0.21.5", "bincode", "bytemuck", "chrono", "cron", + "dashmap", + "futures", "hex", + "json_env_logger", + "kv-log-macro", + "log", + "pretty_assertions", "rand 0.8.5", "reqwest", "rsa", @@ -4469,15 +5064,28 @@ dependencies = [ "serde", "serde_json", "sgx-quote", + "sha2 0.10.7", + "solana-account-decoder", "solana-address-lookup-table-program", "solana-client", "solana-program", "superslice", "switchboard-common", + "switchboard-solana-macros", "tokio", "url", ] +[[package]] +name = "switchboard-solana-macros" +version = "0.2.1" +dependencies = [ + "dotenvy", + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 2.0.28", +] + [[package]] name = "syn" version = "0.15.44" @@ -4495,7 +5103,7 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "unicode-ident", ] @@ -4506,7 +5114,7 @@ version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "unicode-ident", ] @@ -4517,12 +5125,33 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 1.0.109", "unicode-xid 0.2.4", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tap" version = "1.0.1" @@ -4568,35 +5197,24 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.44" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.44" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 2.0.28", ] -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - [[package]] name = "time" version = "0.3.25" @@ -4661,33 +5279,32 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.14.1" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d0183f6f6001549ab68f8c7585093bb732beefbcf6d23a10b9b95c73a1dd49" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", - "memchr", "mio", "num_cpus", - "once_cell", - "parking_lot 0.11.2", + "parking_lot", "pin-project-lite", "signal-hook-registry", + "socket2 0.5.4", "tokio-macros", - "winapi", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "1.8.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", - "syn 1.0.109", + "syn 2.0.28", ] [[package]] @@ -4706,16 +5323,26 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ - "rustls", + "rustls 0.20.9", "tokio", "webpki", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.7", + "tokio", +] + [[package]] name = "tokio-stream" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" dependencies = [ "futures-core", "pin-project-lite", @@ -4730,12 +5357,12 @@ checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" dependencies = [ "futures-util", "log", - "rustls", + "rustls 0.20.9", "tokio", - "tokio-rustls", + "tokio-rustls 0.23.4", "tungstenite", "webpki", - "webpki-roots", + "webpki-roots 0.22.6", ] [[package]] @@ -4761,23 +5388,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_datetime" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" - -[[package]] -name = "toml_edit" -version = "0.19.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" -dependencies = [ - "indexmap 2.0.0", - "toml_datetime", - "winnow", -] - [[package]] name = "tower-service" version = "0.3.2" @@ -4802,7 +5412,7 @@ version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 2.0.28", ] @@ -4835,13 +5445,24 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls", + "rustls 0.20.9", "sha-1", "thiserror", "url", "utf-8", "webpki", - "webpki-roots", + "webpki-roots 0.22.6", +] + +[[package]] +name = "typed-builder" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.32", + "syn 1.0.109", ] [[package]] @@ -4850,6 +5471,15 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.13" @@ -4914,12 +5544,24 @@ dependencies = [ "void", ] +[[package]] +name = "unsigned-varint" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" + [[package]] name = "untrusted" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "uriparse" version = "0.6.4" @@ -4932,9 +5574,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", @@ -4953,6 +5595,42 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +[[package]] +name = "value-bag" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a72e1902dde2bd6441347de2b70b7f5d59bf157c6c62f0c44572607a1d55bbe" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ba39dc791ecb35baad371a3fc04c6eab688c04937d2e0ac6c22b612c0357bf" +dependencies = [ + "erased-serde", + "serde", + "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e06c10810a57bbf45778d023d432a50a1daa7d185991ae06bcfb6c654d0945" +dependencies = [ + "sval", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", +] + [[package]] name = "vcpkg" version = "0.2.15" @@ -4977,6 +5655,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -4992,12 +5680,6 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -5023,7 +5705,7 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 2.0.28", "wasm-bindgen-shared", @@ -5057,7 +5739,7 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 2.0.28", "wasm-bindgen-backend", @@ -5082,12 +5764,12 @@ dependencies = [ [[package]] name = "webpki" -version = "0.22.0" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring", - "untrusted", + "ring 0.17.5", + "untrusted 0.9.0", ] [[package]] @@ -5099,6 +5781,12 @@ dependencies = [ "webpki", ] +[[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + [[package]] name = "winapi" version = "0.3.9" @@ -5286,22 +5974,14 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" -[[package]] -name = "winnow" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acaaa1190073b2b101e15083c38ee8ec891b5e05cbee516521e94ec008f61e64" -dependencies = [ - "memchr", -] - [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys 0.48.0", ] [[package]] @@ -5328,16 +6008,22 @@ dependencies = [ "oid-registry", "rusticata-macros", "thiserror", - "time 0.3.25", + "time", ] +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + [[package]] name = "yasna" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ - "time 0.3.25", + "time", ] [[package]] @@ -5355,7 +6041,7 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.32", "syn 2.0.28", ] diff --git a/rust/switchboard-solana/Cargo.toml b/rust/switchboard-solana/Cargo.toml index 863b6f95a..6a611b72e 100644 --- a/rust/switchboard-solana/Cargo.toml +++ b/rust/switchboard-solana/Cargo.toml @@ -1,7 +1,8 @@ [package] name = "switchboard-solana" -version = "0.28.21" +version = "0.29.70" edition = "2021" +resolver = "2" description = "A Rust library to interact with Switchboard accounts." readme = "README.md" keywords = ["switchboard", "oracle", "solana"] @@ -18,41 +19,58 @@ doctest = false default = ["cpi"] no-entrypoint = [] cpi = ["no-entrypoint"] -secrets = ["rand", "rsa", "reqwest", "serde", "serde_json"] +secrets = ["rand", "rsa", "reqwest"] +macros = ["switchboard-solana-macros"] +ipfs = ["switchboard-common/ipfs"] +all = ["secrets", "macros", "ipfs"] [dependencies] -anchor-spl = "0.28.0" -solana-program = ">= 1.16, < 1.17" -solana-address-lookup-table-program = ">= 1.16, < 1.17" +anchor-spl = "0.29.0" +solana-program = "^1.16" +solana-address-lookup-table-program = "^1.16" rust_decimal = "^1" bytemuck = "^1" superslice = "1" +log = { version = "0.4", features = ["kv_unstable", "kv_unstable_std"] } +kv-log-macro = "1.0" +switchboard-solana-macros = { version = "0.2.1", path = "../switchboard-solana-macros", optional = true, features = [ + "dotenv", +] } [target.'cfg(target_os = "solana")'.dependencies] -switchboard-common = { version = "0.8.20" } -anchor-lang = { version = "0.28.0" } +switchboard-common = { version = "0.11.0" } +anchor-lang = { version = "0.29.0" } [target.'cfg(not(target_os = "solana"))'.dependencies] -switchboard-common = { version = "0.8.20", features = [ - "client", - "solana", +switchboard-common = { version = "0.11.0", features = [ + "client", ] } -anchor-client = { version = "0.28.0" } -solana-client = ">= 1.16, < 1.17" +anchor-client = { version = "0.29.0", features = ["async"] } +solana-client = "^1.16" +solana-account-decoder = "^1.16" +base64 = "0.21.4" bincode = { version = "^1" } sgx-quote = { version = "0.1.0" } cron = { version = "0.12.0" } chrono = { version = "0.4.25" } +futures = "0.3" hex = "0.4.3" tokio = "1" url = "2.4" +serde = { version = "^1", features = ["derive"] } +serde_json = { version = "^1" } +sha2 = "0.10.6" +dashmap = "5.5.3" # Secrets Dependencies rsa = { version = "0.5.0", optional = true } reqwest = { version = "0.11", features = ["json"], optional = true } rand = { version = "0.8.5", optional = true } -serde = { version = "^1", features = ["derive"], optional = true } -serde_json = { version = "^1", optional = true } [package.metadata.docs.rs] rustdoc-args = ["--cfg", "doc_cfg"] + +[dev-dependencies] +json_env_logger = "0.1" +tokio = { version = "1", features = ["full"] } +pretty_assertions = "1.4.0" diff --git a/rust/switchboard-solana/README.md b/rust/switchboard-solana/README.md index e240d3b52..acfe5159c 100644 --- a/rust/switchboard-solana/README.md +++ b/rust/switchboard-solana/README.md @@ -35,10 +35,10 @@ Or add the following line to your Cargo.toml: ```toml [dependencies] -switchboard-solana = "0.28" +switchboard-solana = "0.29" ``` -**NOTE**: The minor version corresponds to the anchor-lang dependency. Version `0.28.*` of this crate uses anchor-lang `0.28.0` while version `0.27.*` of this crate uses anchor-lang `0.27.0`. +**NOTE**: The minor version corresponds to the anchor-lang dependency. Version `0.29.*` of this crate uses anchor-lang `0.29.0` while version `0.27.*` of this crate uses anchor-lang `0.27.0`. We currently support Anchor 29, 28, and 27. ## Accounts diff --git a/rust/switchboard-solana/fixtures/v2_quote.bin b/rust/switchboard-solana/fixtures/v2_quote.bin new file mode 100644 index 000000000..5fc378998 Binary files /dev/null and b/rust/switchboard-solana/fixtures/v2_quote.bin differ diff --git a/rust/switchboard-solana/set-anchor.sh b/rust/switchboard-solana/set-anchor.sh index fed0235c8..3e5aa929a 100755 --- a/rust/switchboard-solana/set-anchor.sh +++ b/rust/switchboard-solana/set-anchor.sh @@ -5,23 +5,58 @@ set -e function set_anchor_27 { was_changed="false" + if [[ -f "Cargo.anchor27.lock" ]]; then - mv Cargo.lock Cargo.anchor28.lock - mv Cargo.anchor27.lock Cargo.lock - was_changed="true" + if [[ -f "Cargo.anchor28.lock" ]]; then + mv Cargo.lock Cargo.anchor29.lock + mv Cargo.anchor27.lock Cargo.lock + was_changed="true" + elif [[ -f "Cargo.anchor29.lock" ]]; then + mv Cargo.lock Cargo.anchor28.lock + mv Cargo.anchor27.lock Cargo.lock + was_changed="true" + fi fi + if [[ -f "Cargo.anchor27.toml" ]]; then - mv Cargo.toml Cargo.anchor28.toml - mv Cargo.anchor27.toml Cargo.toml - was_changed="true" + if [[ -f "Cargo.anchor28.toml" ]]; then + mv Cargo.toml Cargo.anchor29.toml + mv Cargo.anchor27.toml Cargo.toml + was_changed="true" + elif [[ -f "Cargo.anchor29.toml" ]]; then + mv Cargo.toml Cargo.anchor28.toml + mv Cargo.anchor27.toml Cargo.toml + was_changed="true" + fi fi + if [[ -f "src/attestation_program/accounts/request.anchor27.rs" ]]; then - mv src/attestation_program/accounts/request.rs src/attestation_program/accounts/request.anchor28.rs + if [[ -f "src/attestation_program/accounts/request.anchor28.rs" ]]; then + mv src/attestation_program/accounts/request.rs src/attestation_program/accounts/request.anchor29.rs + elif [[ -f "src/attestation_program/accounts/request.anchor29.rs" ]]; then + mv src/attestation_program/accounts/request.rs src/attestation_program/accounts/request.anchor28.rs + fi mv src/attestation_program/accounts/request.anchor27.rs src/attestation_program/accounts/request.rs was_changed="true" fi + if [[ -f "src/attestation_program/accounts/routine.anchor27.rs" ]]; then + mv src/attestation_program/accounts/routine.rs src/attestation_program/accounts/routine.anchor28.rs + mv src/attestation_program/accounts/routine.anchor27.rs src/attestation_program/accounts/routine.rs + was_changed="true" + fi + if [[ -f "src/attestation_program/accounts/service.anchor27.rs" ]]; then + mv src/attestation_program/accounts/service.rs src/attestation_program/accounts/service.anchor28.rs + mv src/attestation_program/accounts/service.anchor27.rs src/attestation_program/accounts/service.rs + was_changed="true" + fi + if [[ -f "src/client/program.anchor27.rs" ]]; then + mv src/client/program.rs src/client/program.anchor28.rs + mv src/client/program.anchor27.rs src/client/program.rs + was_changed="true" + fi + if [[ "${was_changed}" == "true" ]]; then - cargo clean + cargo clean || true cargo build cargo update -p solana-zk-token-sdk --precise 1.14.16 fi @@ -29,31 +64,129 @@ function set_anchor_27 { function set_anchor_28 { was_changed="false" + if [[ -f "Cargo.anchor28.lock" ]]; then - mv Cargo.lock Cargo.anchor27.lock - mv Cargo.anchor28.lock Cargo.lock - was_changed="true" + if [[ -f "Cargo.anchor27.lock" ]]; then + mv Cargo.lock Cargo.anchor29.lock + mv Cargo.anchor28.lock Cargo.lock + was_changed="true" + elif [[ -f "Cargo.anchor29.lock" ]]; then + mv Cargo.lock Cargo.anchor27.lock + mv Cargo.anchor28.lock Cargo.lock + was_changed="true" + fi fi + if [[ -f "Cargo.anchor28.toml" ]]; then - mv Cargo.toml Cargo.anchor27.toml - mv Cargo.anchor28.toml Cargo.toml - was_changed="true" + if [[ -f "Cargo.anchor27.toml" ]]; then + mv Cargo.toml Cargo.anchor29.toml + mv Cargo.anchor28.toml Cargo.toml + was_changed="true" + elif [[ -f "Cargo.anchor29.toml" ]]; then + mv Cargo.toml Cargo.anchor27.toml + mv Cargo.anchor28.toml Cargo.toml + was_changed="true" + fi fi + + # Handle request.rs file renaming logic if [[ -f "src/attestation_program/accounts/request.anchor28.rs" ]]; then - mv src/attestation_program/accounts/request.rs src/attestation_program/accounts/request.anchor27.rs + if [[ -f "src/attestation_program/accounts/request.anchor27.rs" ]]; then + mv src/attestation_program/accounts/request.rs src/attestation_program/accounts/request.anchor29.rs + elif [[ -f "src/attestation_program/accounts/request.anchor29.rs" ]]; then + mv src/attestation_program/accounts/request.rs src/attestation_program/accounts/request.anchor27.rs + fi mv src/attestation_program/accounts/request.anchor28.rs src/attestation_program/accounts/request.rs was_changed="true" fi + if [[ -f "src/attestation_program/accounts/routine.anchor28.rs" ]]; then + mv src/attestation_program/accounts/routine.rs src/attestation_program/accounts/routine.anchor27.rs + mv src/attestation_program/accounts/routine.anchor28.rs src/attestation_program/accounts/routine.rs + was_changed="true" + fi + if [[ -f "src/attestation_program/accounts/service.anchor28.rs" ]]; then + mv src/attestation_program/accounts/service.rs src/attestation_program/accounts/service.anchor27.rs + mv src/attestation_program/accounts/service.anchor28.rs src/attestation_program/accounts/service.rs + was_changed="true" + fi + if [[ -f "src/client/program.anchor28.rs" ]]; then + mv src/client/program.rs src/client/program.anchor27.rs + mv src/client/program.anchor28.rs src/client/program.rs + was_changed="true" + fi + + if [[ "${was_changed}" == "true" ]]; then + cargo clean || true + cargo build + fi +} + +function set_anchor_29 { + was_changed="false" + + if [[ -f "Cargo.anchor29.lock" ]]; then + if [[ -f "Cargo.anchor28.lock" ]]; then + mv Cargo.lock Cargo.anchor27.lock + mv Cargo.anchor29.lock Cargo.lock + was_changed="true" + elif [[ -f "Cargo.anchor27.lock" ]]; then + mv Cargo.lock Cargo.anchor28.lock + mv Cargo.anchor29.lock Cargo.lock + was_changed="true" + fi + fi + + if [[ -f "Cargo.anchor29.toml" ]]; then + if [[ -f "Cargo.anchor27.toml" ]]; then + mv Cargo.toml Cargo.anchor28.toml + mv Cargo.anchor29.toml Cargo.toml + was_changed="true" + elif [[ -f "Cargo.anchor28.toml" ]]; then + mv Cargo.toml Cargo.anchor27.toml + mv Cargo.anchor29.toml Cargo.toml + was_changed="true" + fi + fi + + # Handle request.rs file renaming logic + if [[ -f "src/attestation_program/accounts/request.anchor29.rs" ]]; then + if [[ -f "src/attestation_program/accounts/request.anchor27.rs" ]]; then + mv src/attestation_program/accounts/request.rs src/attestation_program/accounts/request.anchor28.rs + elif [[ -f "src/attestation_program/accounts/request.anchor28.rs" ]]; then + mv src/attestation_program/accounts/request.rs src/attestation_program/accounts/request.anchor27.rs + fi + mv src/attestation_program/accounts/request.anchor29.rs src/attestation_program/accounts/request.rs + was_changed="true" + fi + if [[ -f "src/attestation_program/accounts/routine.anchor27.rs" ]]; then + mv src/attestation_program/accounts/routine.rs src/attestation_program/accounts/routine.anchor28.rs + mv src/attestation_program/accounts/routine.anchor27.rs src/attestation_program/accounts/routine.rs + was_changed="true" + fi + if [[ -f "src/attestation_program/accounts/service.anchor27.rs" ]]; then + mv src/attestation_program/accounts/service.rs src/attestation_program/accounts/service.anchor28.rs + mv src/attestation_program/accounts/service.anchor27.rs src/attestation_program/accounts/service.rs + was_changed="true" + fi + if [[ -f "src/client/program.anchor28.rs" ]]; then + mv src/client/program.rs src/client/program.anchor27.rs + mv src/client/program.anchor28.rs src/client/program.rs + was_changed="true" + fi + if [[ "${was_changed}" == "true" ]]; then - cargo clean + cargo clean || true cargo build fi } + if [[ "$1" == "27" ]]; then set_anchor_27 elif [[ "$1" == "28" ]]; then set_anchor_28 +elif [[ "$1" == "29" ]]; then + set_anchor_29 else echo "" fi diff --git a/rust/switchboard-solana/src/accounts.rs b/rust/switchboard-solana/src/accounts.rs index 86ca32f33..c0c0f338e 100644 --- a/rust/switchboard-solana/src/accounts.rs +++ b/rust/switchboard-solana/src/accounts.rs @@ -7,5 +7,6 @@ pub use crate::oracle_program::accounts::{ pub use crate::attestation_program::accounts::{ AttestationPermissionAccountData, AttestationProgramState, AttestationQueueAccountData, - FunctionAccountData, FunctionRequestAccountData, SwitchboardWallet, VerifierAccountData, + FunctionAccountData, FunctionRequestAccountData, FunctionRoutineAccountData, SwitchboardWallet, + VerifierAccountData, }; diff --git a/rust/switchboard-solana/src/attestation_program/accounts/attestation_permission.rs b/rust/switchboard-solana/src/attestation_program/accounts/attestation_permission.rs index 34357d000..6f41dd6c0 100644 --- a/rust/switchboard-solana/src/attestation_program/accounts/attestation_permission.rs +++ b/rust/switchboard-solana/src/attestation_program/accounts/attestation_permission.rs @@ -1,6 +1,10 @@ use crate::cfg_client; +use crate::*; + use crate::prelude::*; + use bytemuck::{Pod, Zeroable}; + use std::cell::Ref; use crate::SWITCHBOARD_ATTESTATION_PROGRAM_ID; @@ -166,11 +170,25 @@ impl AttestationPermissionAccountData { } cfg_client! { - pub async fn fetch( + pub fn fetch( client: &solana_client::rpc_client::RpcClient, pubkey: Pubkey, - ) -> std::result::Result { - crate::client::load_account(client, pubkey).await + ) -> std::result::Result { + crate::client::fetch_zerocopy_account(client, pubkey) + } + + pub async fn fetch_async( + client: &solana_client::nonblocking::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_async(client, pubkey).await + } + + pub fn fetch_sync( + client: &T, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_sync(client, pubkey) } } @@ -192,7 +210,7 @@ impl AttestationPermissionAccountData { authority: &Pubkey, attestation_queue: &Pubkey, grantee: &Pubkey, - ) -> Result<()> { + ) -> anchor_lang::Result<()> { let key = Self::get_pda(authority, attestation_queue, grantee); if key != *expected { return Err(error!(SwitchboardError::PdaDerivationError)); diff --git a/rust/switchboard-solana/src/attestation_program/accounts/attestation_queue.rs b/rust/switchboard-solana/src/attestation_program/accounts/attestation_queue.rs index 15fcca582..abca7bd17 100644 --- a/rust/switchboard-solana/src/attestation_program/accounts/attestation_queue.rs +++ b/rust/switchboard-solana/src/attestation_program/accounts/attestation_queue.rs @@ -170,11 +170,25 @@ impl AttestationQueueAccountData { } cfg_client! { - pub async fn fetch( + pub fn fetch( client: &solana_client::rpc_client::RpcClient, pubkey: Pubkey, - ) -> std::result::Result { - crate::client::load_account(client, pubkey).await + ) -> std::result::Result { + crate::client::fetch_zerocopy_account(client, pubkey) + } + + pub async fn fetch_async( + client: &solana_client::nonblocking::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_async(client, pubkey).await + } + + pub fn fetch_sync( + client: &T, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_sync(client, pubkey) } } } diff --git a/rust/switchboard-solana/src/attestation_program/accounts/attestation_state.rs b/rust/switchboard-solana/src/attestation_program/accounts/attestation_state.rs index df140f652..c1cdb27ba 100644 --- a/rust/switchboard-solana/src/attestation_program/accounts/attestation_state.rs +++ b/rust/switchboard-solana/src/attestation_program/accounts/attestation_state.rs @@ -80,7 +80,7 @@ impl AttestationProgramState { pda_key } - pub fn verify_pda(expected: &Pubkey) -> Result<()> { + pub fn verify_pda(expected: &Pubkey) -> anchor_lang::Result<()> { let key = Self::get_pda(); if key != *expected { return Err(error!(SwitchboardError::PdaDerivationError)); diff --git a/rust/switchboard-solana/src/attestation_program/accounts/function.rs b/rust/switchboard-solana/src/attestation_program/accounts/function.rs index 56ec964a9..52687f3fe 100644 --- a/rust/switchboard-solana/src/attestation_program/accounts/function.rs +++ b/rust/switchboard-solana/src/attestation_program/accounts/function.rs @@ -1,5 +1,5 @@ -use crate::cfg_client; use crate::prelude::*; +use crate::*; use bytemuck::{Pod, Zeroable}; use std::cell::Ref; @@ -40,17 +40,28 @@ impl From for FunctionStatus { } #[zero_copy(unsafe)] #[repr(packed)] -#[derive(PartialEq)] +#[derive(PartialEq, Debug)] pub struct FunctionAccountData { // Easy Filtering Config /// Whether the function is invoked on a schedule or by request + #[deprecated( + since = "0.28.35", + note = "please use a `FunctionRoutineAccountData` for all scheduled executions" + )] pub is_scheduled: u8, /// Whether the function has been manually triggered with the function_trigger instruction + #[deprecated( + since = "0.28.35", + note = "please use a `FunctionRoutineAccountData` for all scheduled executions" + )] pub is_triggered: u8, + /// The function permissions granted by the attestation_queue.authority pub permissions: u32, pub status: FunctionStatus, + // 15 + // Metadata /// PDA bump. pub bump: u8, @@ -67,12 +78,20 @@ pub struct FunctionAccountData { /// The unix timestamp when the function config (container, registry, version, or schedule) was changed. pub updated_at: i64, + // 392 + // Attestation Config /// The enclave quote + #[deprecated( + since = "0.28.35", + note = "please use a `FunctionRoutineAccountData` for all scheduled executions" + )] pub enclave: Quote, /// An array of permitted mr_enclave measurements for the function. pub mr_enclaves: [[u8; 32]; 32], + // 1849 + // Container Settings /// The off-chain registry to fetch the function container from. pub container_registry: [u8; 64], @@ -81,10 +100,20 @@ pub struct FunctionAccountData { /// The version tag of the container to pull. pub version: [u8; 32], /// The expected schema for the container params. + #[deprecated( + since = "0.28.35", + note = "please use a `FunctionRoutineAccountData` for all scheduled executions" + )] pub params_schema: [u8; 256], /// The default params passed to the container during scheduled execution. + #[deprecated( + since = "0.28.35", + note = "please use a `FunctionRoutineAccountData` for all scheduled executions" + )] pub default_container_params: [u8; 256], + // 2521 + // Accounts Config /// The authority of the function which is authorized to make account changes. pub authority: Pubkey, @@ -95,16 +124,38 @@ pub struct FunctionAccountData { /// The address_lookup_table of the function used to increase the number of accounts we can fit into a function result. pub address_lookup_table: Pubkey, + // 2621 + // Schedule Config /// The cron schedule to run the function on. + #[deprecated( + since = "0.28.35", + note = "please use a `FunctionRoutineAccountData` for all scheduled executions" + )] pub schedule: [u8; 64], /// The unix timestamp when the function was last run. + #[deprecated( + since = "0.28.35", + note = "please use a `FunctionRoutineAccountData` for all scheduled executions" + )] pub last_execution_timestamp: i64, /// The unix timestamp when the function is allowed to run next. + #[deprecated( + since = "0.28.35", + note = "please use a `FunctionRoutineAccountData` for all scheduled executions" + )] pub next_allowed_timestamp: i64, /// The number of times to trigger the function upon the next invocation. + #[deprecated( + since = "0.28.35", + note = "please use a `FunctionRequestAccountData` for all on-demand executions" + )] pub trigger_count: u64, /// Time this function has been sitting in an explicitly triggered state + #[deprecated( + since = "0.28.35", + note = "please use a `FunctionRequestAccountData` for all on-demand executions" + )] pub triggered_since: i64, // Permission Settings @@ -115,17 +166,19 @@ pub struct FunctionAccountData { /// Number of requests created for this function. Used to prevent closing when there are live requests. pub num_requests: u64, /// Whether custom requests have been disabled for this function. - pub requests_disabled: bool, + pub requests_disabled: u8, /// Whether new requests need to be authorized by the FunctionAccount authority before being initialized. /// Useful if you want to use CPIs to control request account creation. - pub requests_require_authorization: bool, + pub requests_require_authorization: u8, /// DEPRECATED. pub reserved1: [u8; 8], - /// The lamports paid to the FunctionAccount escrow on each successful update request. + /// The dev fee that is paid out from the request's escrow to the function's escrow on each successful invocation. + /// This is used to reward the function maintainer for providing the function. + /// 0 = No Fee. Sender = requests's escrow_token_wallet. Receiver = function's reward_token_wallet. pub requests_fee: u64, // Token Config - /// The SwitchboardWallet that will handle pre-funding rewards paid out to function runners. + /// The SwitchboardWallet that will handle pre-funding rewards paid out to function verifiers. pub escrow_wallet: Pubkey, /// The escrow_wallet TokenAccount that handles pre-funding rewards paid out to function runners. pub escrow_token_wallet: Pubkey, @@ -136,10 +189,37 @@ pub struct FunctionAccountData { pub reward_escrow_token_wallet: Pubkey, /// The last reported error code if the most recent response was a failure + #[deprecated( + since = "0.28.35", + note = "please use the error_status field on your function consumer (request or routine)" + )] pub error_status: u8, + // Routines Config + /// Number of routines created for this function. Used to prevent closing when there are live routines. + pub num_routines: u64, + /// Whether custom routines have been disabled for this function. + pub routines_disabled: BoolWithLock, + /// Whether new routines need to be authorized by the FunctionAccount authority before being initialized. + /// Useful if you want to provide AccessControl and only allow certain parties to run routines. + pub routines_require_authorization: u8, + /// The fee that is paid out from the routine's escrow to the function's escrow on each successful invocation. + /// This is used to reward the function maintainer for providing the function. + /// 0 = No Fee. Sender = routine's escrow_token_wallet. Receiver = function's reward_token_wallet. + pub routines_dev_fee: u64, + + /// The functions MRENCLAVE measurement dictating the contents of the secure enclave. + // This represents the last successful execution of a function. + pub mr_enclave: [u8; 32], + /// The VerificationStatus of the quote. + pub verification_status: u8, + /// The unix timestamp when the quote was last verified. + pub verification_timestamp: i64, + /// The unix timestamp when the quotes verification status expires. + pub valid_until: i64, + /// Reserved. - pub _ebuf: [u8; 1023], + pub _ebuf: [u8; 956], } impl Default for FunctionAccountData { @@ -265,51 +345,6 @@ impl FunctionAccountData { )) } - // /// Validate that the provided accounts correspond to the expected function accounts - // /// - // /// # Arguments - // /// - // /// * `function_account_info` - Solana AccountInfo for a FunctionAccountData - // /// * `signer` - Solana AccountInfo for a signer - // pub fn validate_signer2<'a>( - // function_account_info: &AccountInfo<'a>, - // signer: &AccountInfo<'a>, - // ) -> bool { - // let function_loader_result = - // AccountLoader::<'_, FunctionAccountData>::try_from(&function_account_info.clone()); - // if function_loader_result.is_err() { - // return false; - // } - // let func_loader = function_loader_result.unwrap(); - // let func_result = func_loader.load(); - // if func_result.is_err() { - // return false; - // } - // let func = func_result.unwrap(); - - // // TODO: validate the seeds and bump - - // // validate the enclaves enclave is not empty - // if func.enclave.mr_enclave == [0u8; 32] { - // return false; - // } - - // // validate the enclaves delegated signer matches - // if func.enclave.enclave_signer != signer.key() { - // return false; - // } - - // // validate the function was verified and it is not expired - // if let Ok(clock) = Clock::get() { - // return func.enclave.is_verified(&clock); - // } - // if func.enclave.verification_status != VerificationStatus::VerificationSuccess as u8 { - // return false; - // } - - // true - // } - /// Validate that the provided accounts correspond to the expected function accounts /// /// # Arguments @@ -339,13 +374,13 @@ impl FunctionAccountData { /// * `function_account_info` - Solana AccountInfo for a FunctionAccountData /// * `signer` - Solana AccountInfo for a signer pub fn validate_signer<'a>( - function_account_info: &AccountInfo<'a>, + function_account_info: &'a AccountInfo<'a>, signer: &AccountInfo<'a>, ) -> anchor_lang::Result { // deserialize accounts and verify the owner let function_loader = - AccountLoader::<'_, FunctionAccountData>::try_from(&function_account_info.clone())?; + AccountLoader::<'_, FunctionAccountData>::try_from(function_account_info)?; let func = function_loader.load()?; // TODO: validate the seeds and bump @@ -364,143 +399,450 @@ impl FunctionAccountData { Ok(func.enclave.is_verified(&Clock::get()?)) } + #[deprecated( + since = "0.28.35", + note = "please use a `FunctionRoutineAccountData` for all scheduled executions" + )] pub fn is_empty_schedule(&self) -> bool { - if self.schedule == [0u8; 64] { - return true; - } - let first_byte_null = self - .schedule + self.schedule .first() .map(|&byte| byte == 0) - .unwrap_or(false); - if first_byte_null { - return true; - } - - false + .unwrap_or(false) } pub fn get_container(&self) -> String { std::str::from_utf8(&self.container) .unwrap_or("") + .trim() + .to_string() + } + + pub fn get_container_registry(&self) -> String { + std::str::from_utf8(&self.container_registry) + .unwrap_or("") + .trim() .to_string() } pub fn get_version(&self) -> String { - std::str::from_utf8(&self.version) + let version = std::str::from_utf8(&self.version) .unwrap_or("latest") - .to_string() + .trim() + .to_string(); + + if version.is_empty() { + String::from("latest") + } else { + version + } } pub fn get_name(&self) -> String { - format!("{}:{}", self.get_container(), self.get_version()) + format!("{}:{}", self.get_container(), self.get_version()).replace('\u{0}', "") } - cfg_client! { - pub fn get_discriminator_filter() -> solana_client::rpc_filter::RpcFilterType { - solana_client::rpc_filter::RpcFilterType::Memcmp(solana_client::rpc_filter::Memcmp::new_raw_bytes( - 0, - FunctionAccountData::discriminator().to_vec(), - )) - } + pub fn get_function_name(&self) -> String { + std::str::from_utf8(&self.name) + .unwrap_or("") + .trim() + .to_string() + } - pub fn get_is_triggered_filter() -> solana_client::rpc_filter::RpcFilterType { - solana_client::rpc_filter::RpcFilterType::Memcmp(solana_client::rpc_filter::Memcmp::new_raw_bytes( - 9, - vec![1u8], - )) + /// Asserts that the permissions are valid for the given queue's access control level. + /// + /// # Arguments + /// + /// * `queue_require_usage_permissions` - A boolean indicating whether queue usage permissions are required. + /// + /// # Errors + /// + /// Returns an error if the queue usage permissions are required but not present. + pub fn assert_permissions( + &self, + queue_require_usage_permissions: bool, + ) -> anchor_lang::Result<()> { + if queue_require_usage_permissions + && self.permissions != SwitchboardAttestationPermission::PermitQueueUsage as u32 + { + return Err(error!(SwitchboardError::PermissionDenied)); } - pub fn get_is_scheduled_filter() -> solana_client::rpc_filter::RpcFilterType { - solana_client::rpc_filter::RpcFilterType::Memcmp(solana_client::rpc_filter::Memcmp::new_raw_bytes( - 8, - vec![1u8], - )) - } + Ok(()) + } - pub fn get_is_active_filter() -> solana_client::rpc_filter::RpcFilterType { - solana_client::rpc_filter::RpcFilterType::Memcmp(solana_client::rpc_filter::Memcmp::new_raw_bytes( - 14, - vec![FunctionStatus::Active as u8], - )) + /// Asserts that the given `mr_enclave` is valid by checking it against the enclave set. + /// If the `mr_enclave` is invalid, returns an `InvalidMrEnclave` error. + pub fn assert_mr_enclave(&self, mr_enclave: &[u8; 32]) -> anchor_lang::Result<()> { + if !self.is_valid_enclave(mr_enclave) { + return Err(error!(SwitchboardError::InvalidMrEnclave)); } - pub fn get_queue_filter(queue_pubkey: &Pubkey) -> solana_client::rpc_filter::RpcFilterType { - solana_client::rpc_filter::RpcFilterType::Memcmp(solana_client::rpc_filter::Memcmp::new_raw_bytes( - 2553, - queue_pubkey.to_bytes().into(), - )) - } + Ok(()) + } - pub fn get_is_ready_filters(queue_pubkey: &Pubkey) -> Vec { - vec![ - FunctionAccountData::get_discriminator_filter(), - FunctionAccountData::get_is_triggered_filter(), - FunctionAccountData::get_is_scheduled_filter(), - FunctionAccountData::get_is_active_filter(), - FunctionAccountData::get_queue_filter(queue_pubkey), - ] + /// Checks if the given `mr_enclave` is valid by verifying if it exists in the list of valid + /// `mr_enclaves` stored in the current instance of `FunctionImpl`. + /// + /// # Arguments + /// + /// * `mr_enclave` - A reference to a 32-byte array representing the `mr_enclave` value of the + /// enclave to be validated. + /// + /// # Returns + /// + /// A boolean value indicating whether the given `mr_enclave` is valid or not. + pub fn is_valid_enclave(&self, mr_enclave: &[u8; 32]) -> bool { + if *mr_enclave == [0u8; 32] { + return false; } - pub fn get_schedule(&self) -> Option { - if self.schedule[0] == 0 { - return None; + self.mr_enclaves.contains(mr_enclave) + } + + /// Parses the enclave measurements and returns a vector of 32-byte arrays representing the non-empty mr_enclaves. + /// + /// # Example + /// + /// ``` + /// use crate::FunctionAccountData; + /// + /// let function = FunctionAccountData::default(); + /// let parsed_enclaves = function.parse_enclaves(); + /// assert_eq(0, parsed_enclaves.len()); + /// ``` + pub fn parse_enclaves(&self) -> Vec<[u8; 32]> { + let mut parsed_enclaves: Vec<[u8; 32]> = vec![]; + for mr_enclave in self.mr_enclaves.iter() { + if *mr_enclave != [0u8; 32] { + parsed_enclaves.push(*mr_enclave) } - let every_second = cron::Schedule::try_from("* * * * * *").unwrap(); - let schedule = std::str::from_utf8(&self.schedule) - .unwrap_or("* * * * * *") - .trim_end_matches('\0'); - let schedule = cron::Schedule::try_from(schedule); - Some(schedule.unwrap_or(every_second)) } + parsed_enclaves + } - pub fn get_last_execution_datetime(&self) -> chrono::DateTime { - chrono::DateTime::from_utc( - chrono::NaiveDateTime::from_timestamp_opt(self.last_execution_timestamp, 0).unwrap(), - chrono::Utc, - ) + /// Asserts that the current instance has enclaves. + /// + /// # Errors + /// + /// Returns an error of type `SwitchboardError::MrEnclavesEmpty` if the enclaves are empty. + pub fn assert_has_enclaves(&self) -> anchor_lang::Result<()> { + if self.parse_enclaves().is_empty() { + return Err(error!(SwitchboardError::MrEnclavesEmpty)); } - pub fn get_next_execution_datetime(&self) -> Option> { - let schedule = self.get_schedule()?; - schedule.after(&self.get_last_execution_datetime()).next() + Ok(()) + } + + /// Asserts that requests are enabled for the given function. + /// + /// # Errors + /// + /// Returns an error of type `SwitchboardError::UserRequestsDisabled` if the function has requests_disabled configured. + fn assert_requests_enabled(&self) -> anchor_lang::Result<()> { + if self.requests_disabled.to_bool() { + return Err(error!(SwitchboardError::UserRequestsDisabled)); } - pub fn should_execute(&self, now: chrono::DateTime) -> bool { - if self.is_triggered > 0 { - return true; - } - let schedule = self.get_schedule(); - if schedule.is_none() { - return false; - } - let dt = self.get_last_execution_datetime(); - let next_trigger_time = schedule.unwrap().after(&dt).next(); - if next_trigger_time.is_none() { - return false; - } - let next_trigger_time = next_trigger_time.unwrap(); - if next_trigger_time > now { - return false; - } - true + Ok(()) + } + + /// Asserts that routines are enabled for the given function. + /// + /// # Errors + /// + /// Returns an error of type `SwitchboardError::FunctionRoutinesDisabled` if the function has routines_disabled configured. + fn assert_routines_enabled(&self) -> anchor_lang::Result<()> { + if self.routines_disabled.is_disabled() { + return Err(error!(SwitchboardError::FunctionRoutinesDisabled)); + } + + Ok(()) + } + + /// Checks if the function is ready to execute routines. + /// + /// # Errors + /// + /// Returns an error if: + /// + /// - Routines are disabled. + /// - The function has 0 valid mr_enclaves. + /// - The function status is not `Active`. + /// + /// # Returns + /// + /// Returns `Ok(())` if the function is ready to execute routines. + pub fn ready_for_routines(&self) -> anchor_lang::Result<()> { + self.assert_routines_enabled()?; + self.assert_has_enclaves()?; + + if self.status != FunctionStatus::Active { + return Err(error!(SwitchboardError::FunctionNotReady)); } - pub fn is_scheduled(&self) -> bool { - self.schedule[0] == 0 + Ok(()) + } + + /// Checks if the function is ready to execute requests. + /// + /// # Errors + /// + /// Returns an error if: + /// + /// - Requests are disabled. + /// - The function has 0 valid mr_enclaves. + /// - The function status is not `Active`. + /// + /// # Returns + /// + /// Returns `Ok(())` if the function is ready to execute requests. + pub fn ready_for_requests(&self) -> anchor_lang::Result<()> { + self.assert_requests_enabled()?; + self.assert_has_enclaves()?; + + if self.status != FunctionStatus::Active && self.status != FunctionStatus::OutOfFunds { + return Err(error!(SwitchboardError::FunctionNotReady)); } - pub async fn fetch( - client: &solana_client::rpc_client::RpcClient, - pubkey: Pubkey, - ) -> std::result::Result { - crate::client::load_account(client, pubkey).await + Ok(()) + } + + /// Returns the public key of the reward token wallet. If the reward escrow token wallet is set, + /// it returns the reward escrow token wallet. Otherwise, it returns the escrow token wallet. + pub fn get_reward_token_wallet(&self) -> Pubkey { + if self.reward_escrow_token_wallet != Pubkey::default() { + self.reward_escrow_token_wallet + } else { + self.escrow_token_wallet } + } +} +#[cfg(test)] +mod tests { + use super::*; + + use std::str::FromStr; + + const FUNCTION_DATA: [u8; 3903] = [ + 76, 139, 47, 44, 240, 182, 148, 200, 1, 0, 0, 0, 0, 0, 1, 254, 218, 146, 221, 148, 1, 120, + 215, 193, 125, 114, 207, 207, 22, 231, 179, 145, 88, 164, 177, 30, 89, 129, 230, 41, 12, + 196, 209, 106, 74, 219, 84, 225, 83, 111, 108, 97, 110, 97, 32, 84, 97, 115, 107, 32, 82, + 117, 110, 110, 101, 114, 32, 70, 117, 110, 99, 116, 105, 111, 110, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 199, 18, 218, 14, 0, 0, 0, 0, 227, 58, 32, + 101, 0, 0, 0, 0, 236, 84, 32, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, + 225, 147, 52, 198, 184, 237, 187, 106, 131, 221, 177, 176, 80, 145, 117, 118, 50, 205, 62, + 19, 161, 35, 83, 210, 209, 6, 138, 101, 21, 112, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 111, 99, 107, 101, 114, + 104, 117, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, + 119, 105, 116, 99, 104, 98, 111, 97, 114, 100, 108, 97, 98, 115, 47, 115, 111, 108, 97, + 110, 97, 45, 116, 97, 115, 107, 45, 114, 117, 110, 110, 101, 114, 45, 102, 117, 110, 99, + 116, 105, 111, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 97, + 116, 101, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 218, 146, 221, 148, 1, 120, 215, 193, 125, 114, 207, 207, 22, 231, 179, 145, + 88, 164, 177, 30, 89, 129, 230, 41, 12, 196, 209, 106, 74, 219, 84, 225, 174, 177, 70, 231, + 73, 196, 214, 194, 190, 219, 159, 24, 162, 119, 159, 16, 120, 53, 239, 102, 225, 241, 66, + 97, 108, 144, 152, 47, 53, 76, 242, 215, 0, 0, 0, 0, 70, 65, 33, 246, 149, 218, 240, 26, + 241, 158, 100, 187, 243, 161, 203, 30, 151, 239, 214, 115, 213, 239, 24, 92, 137, 228, 4, + 197, 143, 13, 48, 131, 42, 32, 42, 47, 53, 32, 42, 32, 42, 32, 42, 32, 42, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118, 120, 45, 101, 0, 0, 0, 0, 149, 120, + 45, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 249, + 132, 49, 100, 114, 123, 49, 150, 198, 234, 193, 130, 176, 237, 177, 72, 2, 22, 174, 106, + 202, 197, 89, 28, 119, 35, 166, 73, 57, 38, 23, 116, 180, 233, 161, 252, 164, 99, 206, 179, + 104, 122, 218, 86, 162, 24, 43, 248, 82, 63, 111, 64, 70, 179, 213, 70, 253, 4, 4, 203, 25, + 32, 254, 160, 249, 132, 49, 100, 114, 123, 49, 150, 198, 234, 193, 130, 176, 237, 177, 72, + 2, 22, 174, 106, 202, 197, 89, 28, 119, 35, 166, 73, 57, 38, 23, 116, 180, 233, 161, 252, + 164, 99, 206, 179, 104, 122, 218, 86, 162, 24, 43, 248, 82, 63, 111, 64, 70, 179, 213, 70, + 253, 4, 4, 203, 25, 32, 254, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + + const FUNCTION_DATA_HEX: &str = "4c8b2f2cf0b694c801000000000001feda92dd940178d7c17d72cfcf16e7b39158a4b11e5981e6290cc4d16a4adb54e1536f6c616e61205461736b2052756e6e65722046756e6374696f6e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c712da0e00000000e33a206500000000ec542065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023e19334c6b8edbb6a83ddb1b05091757632cd3e13a12353d2d1068a6515707d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000646f636b657268756200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000737769746368626f6172646c6162732f736f6c616e612d7461736b2d72756e6e65722d66756e6374696f6e0000000000000000000000000000000000000000006c617465737400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000da92dd940178d7c17d72cfcf16e7b39158a4b11e5981e6290cc4d16a4adb54e1aeb146e749c4d6c2bedb9f18a2779f107835ef66e1f142616c90982f354cf2d700000000464121f695daf01af19e64bbf3a1cb1e97efd673d5ef185c89e404c58f0d30832a202a2f35202a202a202a202a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076782d650000000095782d65000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0f9843164727b3196c6eac182b0edb1480216ae6acac5591c7723a64939261774b4e9a1fca463ceb3687ada56a2182bf8523f6f4046b3d546fd0404cb1920fea0f9843164727b3196c6eac182b0edb1480216ae6acac5591c7723a64939261774b4e9a1fca463ceb3687ada56a2182bf8523f6f4046b3d546fd0404cb1920feff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + + #[test] + fn test_function_deserialization() { + let function = + FunctionAccountData::try_deserialize_unchecked(&mut FUNCTION_DATA.as_slice()).unwrap(); + + assert_eq!( + std::str::from_utf8(&function.container) + .unwrap() + .to_string() + .trim_matches(char::from(0)), + "switchboardlabs/solana-task-runner-function" + ); + + assert_eq!( + std::str::from_utf8(&function.container_registry) + .unwrap() + .to_string() + .trim_matches(char::from(0)), + "dockerhub" + ); + + assert_eq!( + std::str::from_utf8(&function.version) + .unwrap() + .to_string() + .trim_matches(char::from(0)), + "latest" + ); + + assert_eq!( + function.attestation_queue, + Pubkey::from_str("CkvizjVnm2zA5Wuwan34NhVT3zFc7vqUyGnA6tuEF5aE").unwrap() + ); + + assert_eq!( + function.authority, + Pubkey::from_str("FiDmUK83DTc1ijEyVnwMoQwJ6W4gC2S8JhncKsheDQTJ").unwrap() + ); + } - // pub async fn get_program_accounts( - // client: &solana_client::rpc_client::RpcClient - // ) -> std::result::Result, switchboard_common::Error> { - // let accounts = client.get_program_accounts(&SWITCHBOARD_ATTESTATION_PROGRAM_ID)?; - // } + #[test] + fn test_hex_decode() { + let account_bytes = hex::decode(FUNCTION_DATA_HEX).unwrap(); + let function = FunctionAccountData::try_deserialize(&mut account_bytes.as_slice()).unwrap(); + + assert_eq!( + std::str::from_utf8(&function.container) + .unwrap() + .to_string() + .trim_matches(char::from(0)), + "switchboardlabs/solana-task-runner-function" + ); + + assert_eq!( + std::str::from_utf8(&function.container_registry) + .unwrap() + .to_string() + .trim_matches(char::from(0)), + "dockerhub" + ); + + assert_eq!( + std::str::from_utf8(&function.version) + .unwrap() + .to_string() + .trim_matches(char::from(0)), + "latest" + ); + + assert_eq!( + function.attestation_queue, + Pubkey::from_str("CkvizjVnm2zA5Wuwan34NhVT3zFc7vqUyGnA6tuEF5aE").unwrap() + ); + + assert_eq!( + function.authority, + Pubkey::from_str("FiDmUK83DTc1ijEyVnwMoQwJ6W4gC2S8JhncKsheDQTJ").unwrap() + ); } } diff --git a/rust/switchboard-solana/src/attestation_program/accounts/mod.rs b/rust/switchboard-solana/src/attestation_program/accounts/mod.rs index a1aaacef8..c0bd27005 100644 --- a/rust/switchboard-solana/src/attestation_program/accounts/mod.rs +++ b/rust/switchboard-solana/src/attestation_program/accounts/mod.rs @@ -3,6 +3,7 @@ pub mod attestation_queue; pub mod attestation_state; pub mod function; pub mod request; +pub mod routine; pub mod switchboard_wallet; pub mod verifier; @@ -11,5 +12,6 @@ pub use attestation_queue::*; pub use attestation_state::*; pub use function::*; pub use request::*; +pub use routine::*; pub use switchboard_wallet::*; pub use verifier::*; diff --git a/rust/switchboard-solana/src/attestation_program/accounts/request.anchor27.rs b/rust/switchboard-solana/src/attestation_program/accounts/request.anchor27.rs index d67027797..130b770a3 100644 --- a/rust/switchboard-solana/src/attestation_program/accounts/request.anchor27.rs +++ b/rust/switchboard-solana/src/attestation_program/accounts/request.anchor27.rs @@ -1,16 +1,6 @@ -use crate::{cfg_client, prelude::*}; +use crate::prelude::*; use solana_program::borsh::get_instance_packed_len; -fn serialize_slice( - slice: &[T], - writer: &mut W, -) -> std::result::Result<(), std::io::Error> { - for item in slice { - item.serialize(writer)?; - } - Ok(()) -} - #[repr(u8)] #[derive(Copy, Clone, Default, Debug, Eq, PartialEq, AnchorSerialize, AnchorDeserialize)] pub enum RequestStatus { @@ -22,6 +12,11 @@ pub enum RequestStatus { RequestExpired = 4, RequestSuccess = 5, } +impl RequestStatus { + pub fn is_active(&self) -> bool { + matches!(self, RequestStatus::RequestPending) + } +} impl From for u8 { fn from(value: RequestStatus) -> Self { match value { @@ -47,6 +42,16 @@ impl From for RequestStatus { } } +fn serialize_slice( + slice: &[T], + writer: &mut W, +) -> std::result::Result<(), std::io::Error> { + for item in slice { + item.serialize(writer)?; + } + Ok(()) +} + #[derive(Copy, Clone, PartialEq)] pub struct FunctionRequestTriggerRound { /// The status of the request. @@ -68,8 +73,11 @@ pub struct FunctionRequestTriggerRound { /// The slot when the request can first be executed. pub valid_after_slot: u64, + /// The index of the verifier assigned to this request. + pub queue_idx: u32, + /// Reserved. - pub _ebuf: [u8; 56], + pub _ebuf: [u8; 52], } impl Default for FunctionRequestTriggerRound { fn default() -> Self { @@ -79,8 +87,8 @@ impl Default for FunctionRequestTriggerRound { fn deserialize_round_ebuf_slice( reader: &mut R, -) -> std::result::Result<[u8; 56], std::io::Error> { - let mut buffer = [0u8; 56]; +) -> std::result::Result<[u8; 52], std::io::Error> { + let mut buffer = [0u8; 52]; reader.read_exact(&mut buffer)?; Ok(buffer) } @@ -108,9 +116,8 @@ where borsh::BorshSerialize::serialize(&self.verifier, writer)?; borsh::BorshSerialize::serialize(&self.enclave_signer, writer)?; borsh::BorshSerialize::serialize(&self.valid_after_slot, writer)?; + borsh::BorshSerialize::serialize(&self.queue_idx, writer)?; serialize_slice(&self._ebuf, writer)?; - // writer.write_all(&[0u8; 56])?; - // borsh::BorshSerialize::serialize(&[0u8; 56], writer)?; Ok(()) } } @@ -135,9 +142,12 @@ where verifier: borsh::BorshDeserialize::deserialize(buf)?, enclave_signer: borsh::BorshDeserialize::deserialize(buf)?, valid_after_slot: borsh::BorshDeserialize::deserialize(buf)?, + queue_idx: borsh::BorshDeserialize::deserialize(buf)?, _ebuf: deserialize_round_ebuf_slice(buf)?, }) } + + } // #[account] @@ -182,6 +192,7 @@ pub struct FunctionRequestAccountData { /// The slot when the account can be garbage collected and closed by anyone for a portion of the rent. pub garbage_collection_slot: Option, + /// The last recorded error code if most recent response was an error. pub error_status: u8, /// Reserved. @@ -210,29 +221,6 @@ impl Default for FunctionRequestAccountData { } } -// pub struct U8Array255([u8; 255]); - -// impl borsh::de::BorshDeserialize for U8Array255 { -// // fn deserialize_reader( -// // reader: &mut R, -// // ) -> ::core::result::Result { -// // let mut buffer = [0u8; 255]; -// // reader.read_exact(&mut buffer)?; -// // Ok(U8Array255(buffer)) -// // } - -// fn deserialize(reader: &mut &[u8]) -> std::result::Result { -// // Ok([0u8; 255]) -// Ok(U8Array255([0u8; 255])) -// } -// } - -// fn deserialize_ebuf_slice( -// reader: &mut R, -// ) -> std::result::Result<[u8; 255], std::io::Error> { -// Ok([0u8; 255]) -// } - fn deserialize_ebuf_slice( reader: &mut R, ) -> std::result::Result<[u8; 255], std::io::Error> { @@ -309,6 +297,8 @@ where _ebuf: deserialize_ebuf_slice(buf)?, }) } + + } impl anchor_lang::AccountSerialize for FunctionRequestAccountData { @@ -374,46 +364,99 @@ impl FunctionRequestAccountData { pub fn space(len: Option) -> usize { let base: usize = 8 // discriminator + get_instance_packed_len(&FunctionRequestAccountData::default()).unwrap(); - let vec_elements: usize = len.unwrap_or(crate::DEFAULT_USERS_CONTAINER_PARAMS_LEN) as usize; + let vec_elements: usize = len.unwrap_or(crate::DEFAULT_MAX_CONTAINER_PARAMS_LEN) as usize; base + vec_elements } // verify if their is a non-expired pending request pub fn is_round_active(&self, clock: &Clock) -> bool { - if self.active_request.status == RequestStatus::RequestPending - && self.active_request.expiration_slot > 0 + // 1. check status enum + if !self.active_request.status.is_active() { + return false; + } + + // 2. check valid after slot + // TODO: we should throw a more descriptive error for this + if clock.slot < self.active_request.valid_after_slot { + return false; + } + + // 3. check expiration + if self.active_request.expiration_slot > 0 && clock.slot >= self.active_request.expiration_slot { - return true; + return false; } - false + true } + /// Validates the given `signer` account against the `function_account_info` and the `active_request` + /// stored in this `FunctionRequestAccountData`. + /// + /// # Arguments + /// + /// * `function_account_info` - The `AccountInfo` of the function account. + /// * `signer` - The `AccountInfo` of the account to validate. + /// + /// # Errors + /// + /// Returns an error if the function account data cannot be loaded or if the `signer` account does not match + /// the expected `enclave_signer` stored in the `active_request`. + /// + /// # Returns + /// + /// Returns `Ok(true)` if the validation succeeds, `Ok(false)` otherwise. + /// + /// # Examples + /// + /// ```ignore + /// use switchboard_solana::FunctionRequestAccountData; + /// + /// #[derive(Accounts)] + /// pub struct Settle<'info> { + /// // YOUR PROGRAM ACCOUNTS + /// #[account( + /// mut, + /// has_one = switchboard_request, + /// )] + /// pub user: AccountLoader<'info, UserState>, + /// + /// // SWITCHBOARD ACCOUNTS + /// pub switchboard_function: AccountLoader<'info, FunctionAccountData>, + /// #[account( + /// constraint = switchboard_request.validate_signer( + /// &switchboard_function.to_account_info(), + /// &enclave_signer.to_account_info() + /// )? + /// )] + /// pub switchboard_request: Box>, + /// pub enclave_signer: Signer<'info>, + /// } + /// ``` pub fn validate_signer<'a>( &self, - function_account_info: &AccountInfo<'a>, + function_account_info: &'a AccountInfo<'a>, signer: &AccountInfo<'a>, ) -> anchor_lang::Result { - if self.function != function_account_info.key() { - msg!("function key mismatch"); + let function_loader = + AccountLoader::<'a, FunctionAccountData>::try_from(function_account_info)?; + + if self.function != function_loader.key() { msg!( - "expected {}, received {}", + "FunctionMismatch: expected {}, received {}", self.function, - function_account_info.key() + function_loader.key() ); return Ok(false); } - let function_loader = - AccountLoader::<'_, FunctionAccountData>::try_from(&function_account_info.clone())?; function_loader.load()?; // check owner/discriminator // validate the enclaves delegated signer matches if self.active_request.enclave_signer != signer.key() { - msg!("request signer mismatch"); msg!( - "expected {}, received {}", + "SignerMismatch: expected {}, received {}", self.active_request.enclave_signer, signer.key() ); @@ -422,52 +465,6 @@ impl FunctionRequestAccountData { Ok(true) } - - cfg_client! { - pub fn get_discriminator_filter() -> solana_client::rpc_filter::RpcFilterType { - solana_client::rpc_filter::RpcFilterType::Memcmp(solana_client::rpc_filter::Memcmp::new_raw_bytes( - 0, - FunctionRequestAccountData::discriminator().to_vec(), - )) - } - - pub fn get_is_triggered_filter() -> solana_client::rpc_filter::RpcFilterType { - solana_client::rpc_filter::RpcFilterType::Memcmp(solana_client::rpc_filter::Memcmp::new_raw_bytes( - 8, - vec![1u8], - )) - } - - pub fn get_is_active_filter() -> solana_client::rpc_filter::RpcFilterType { - solana_client::rpc_filter::RpcFilterType::Memcmp(solana_client::rpc_filter::Memcmp::new_raw_bytes( - 9, - vec![RequestStatus::RequestPending as u8], - )) - } - - pub fn get_queue_filter(queue_pubkey: &Pubkey) -> solana_client::rpc_filter::RpcFilterType { - solana_client::rpc_filter::RpcFilterType::Memcmp(solana_client::rpc_filter::Memcmp::new_raw_bytes( - 138, - queue_pubkey.to_bytes().into(), - )) - } - - pub fn get_is_ready_filters(queue_pubkey: &Pubkey) -> Vec { - vec![ - FunctionRequestAccountData::get_discriminator_filter(), - FunctionRequestAccountData::get_is_triggered_filter(), - FunctionRequestAccountData::get_is_active_filter(), - FunctionRequestAccountData::get_queue_filter(queue_pubkey), - ] - } - - pub async fn fetch( - client: &solana_client::rpc_client::RpcClient, - pubkey: Pubkey, - ) -> std::result::Result { - crate::client::fetch_anchor_account(client, pubkey).await - } - } } #[cfg(test)] @@ -531,9 +528,6 @@ mod tests { const REQUEST_DATA_HEX: &str = "080eb155904194f60004bfa35f95fbc43d26aa1ec0d2eed279fb735088b7745807c37fe104b1a7fad6620000000000000000000000000000000000000000000000000000000000000000c85b2185fb4d042d2158a0db4afdbf38bf3482572cc54e2f40010931172ef87643fed7bbb351c65427f4107159382985424744eec622e2db4196fcf3e58c9970aeb146e749c4d6c2bedb9f18a2779f107835ef66e1f142616c90982f354cf2d7040000000000000000d4999a0e00000000e1999a0e000000000000000000000000d6b01e18eceef561dac92214195eeb58eb3072c1907edce98eee20bfe9dcaf1750e9e4c05724b46b05b6467d598b440576dad1a7cf34144cd9f15c326a35fd3c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200009f36664d43eb1a5e90ac12412d367f3b64d5ce5b2865f8bdc313a5be7be336677d0000005049443d45354d41737a6a7a38715a5a44484b715132316735775975684d546a4d626b314c344c346a4246584d6771472c4d494e5f524553554c543d312c4d41585f524553554c543d31302c555345523d4475354d6f34594646464c7154394b5a514b504d7734436d656f355666474c75726a63526878686233706a4b82c00865000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - // Already has discriminator removed - const REQUEST_DATA_HEX_NO_DISC: &str = "0004bfa35f95fbc43d26aa1ec0d2eed279fb735088b7745807c37fe104b1a7fad6620000000000000000000000000000000000000000000000000000000000000000c85b2185fb4d042d2158a0db4afdbf38bf3482572cc54e2f40010931172ef87643fed7bbb351c65427f4107159382985424744eec622e2db4196fcf3e58c9970aeb146e749c4d6c2bedb9f18a2779f107835ef66e1f142616c90982f354cf2d7040000000000000000d4999a0e00000000e1999a0e000000000000000000000000d6b01e18eceef561dac92214195eeb58eb3072c1907edce98eee20bfe9dcaf1750e9e4c05724b46b05b6467d598b440576dad1a7cf34144cd9f15c326a35fd3c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200009f36664d43eb1a5e90ac12412d367f3b64d5ce5b2865f8bdc313a5be7be336677d0000005049443d45354d41737a6a7a38715a5a44484b715132316735775975684d546a4d626b314c344c346a4246584d6771472c4d494e5f524553554c543d312c4d41585f524553554c543d31302c555345523d4475354d6f34594646464c7154394b5a514b504d7734436d656f355666474c75726a63526878686233706a4b82c00865000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - const EXPECTED_CONTAINER_PARAMS: &str = "PID=E5MAszjz8qZZDHKqQ21g5wYuhMTjMbk1L4L4jBFXMgqG,MIN_RESULT=1,MAX_RESULT=10,USER=Du5Mo4YFFFLqT9KZQKPMw4Cmeo5VfGLurjcRhxhb3pjK"; #[test] @@ -546,9 +540,6 @@ mod tests { .unwrap() .to_string(); - println!("Max params Len: {}", request.max_container_params_len); - println!("Params Len: {}", request.container_params.len()); - assert_eq!(container_params, EXPECTED_CONTAINER_PARAMS.to_string()); assert_eq!( request.function, diff --git a/rust/switchboard-solana/src/attestation_program/accounts/request.anchor28.rs b/rust/switchboard-solana/src/attestation_program/accounts/request.anchor28.rs new file mode 100644 index 000000000..567eabec4 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/accounts/request.anchor28.rs @@ -0,0 +1,441 @@ +use crate::prelude::*; +use solana_program::borsh0_10::get_instance_packed_len; + +#[repr(u8)] +#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, AnchorSerialize, AnchorDeserialize)] +pub enum RequestStatus { + #[default] + None = 0, + RequestPending = 1, + RequestCancelled = 2, + RequestFailure = 3, + RequestExpired = 4, + RequestSuccess = 5, +} +impl RequestStatus { + pub fn is_active(&self) -> bool { + matches!(self, RequestStatus::RequestPending) + } +} +impl From for u8 { + fn from(value: RequestStatus) -> Self { + match value { + RequestStatus::RequestPending => 1, + RequestStatus::RequestCancelled => 2, + RequestStatus::RequestFailure => 3, + RequestStatus::RequestExpired => 4, + RequestStatus::RequestSuccess => 5, + _ => 0, + } + } +} +impl From for RequestStatus { + fn from(value: u8) -> Self { + match value { + 1 => RequestStatus::RequestPending, + 2 => RequestStatus::RequestCancelled, + 3 => RequestStatus::RequestFailure, + 4 => RequestStatus::RequestExpired, + 5 => RequestStatus::RequestSuccess, + _ => RequestStatus::default(), + } + } +} + +#[derive(Copy, Clone, AnchorDeserialize, AnchorSerialize, PartialEq)] +pub struct FunctionRequestTriggerRound { + /// The status of the request. + pub status: RequestStatus, + /// The SOL bounty in lamports used to incentivize a verifier to expedite the request. + pub bounty: u64, + /// The slot the request was published + pub request_slot: u64, + /// The slot when the request was fulfilled + pub fulfilled_slot: u64, + /// The slot when the request will expire and be able to be closed by the non-authority account + pub expiration_slot: u64, + /// The EnclaveAccount who verified the enclave for this request + pub verifier: Pubkey, + /// The keypair generated in the enclave and required to sign any + /// valid transactions processed by the function. + pub enclave_signer: Pubkey, + + /// The slot when the request can first be executed. + pub valid_after_slot: u64, + + /// The index of the verifier assigned to this request. + pub queue_idx: u32, + + /// Reserved. + pub _ebuf: [u8; 52], +} +impl Default for FunctionRequestTriggerRound { + fn default() -> Self { + unsafe { std::mem::zeroed() } + } +} + +// #[account] +#[derive(AnchorDeserialize, AnchorSerialize, Clone, PartialEq)] +pub struct FunctionRequestAccountData { + // Up-Front Params for RPC filtering + /// Whether the request is ready to be processed. + pub is_triggered: u8, + /// The status of the current request. + pub status: RequestStatus, + + // Accounts + /// Signer allowed to cancel the request. + pub authority: Pubkey, + /// The default destination for rent exemption when the account is closed. + pub payer: Pubkey, + /// The function that can process this request + pub function: Pubkey, + /// The tokenAccount escrow + pub escrow: Pubkey, + /// The Attestation Queue for this request. + pub attestation_queue: Pubkey, + + // Rounds + /// The current active request. + pub active_request: FunctionRequestTriggerRound, + /// The previous request. + pub previous_request: FunctionRequestTriggerRound, + + // Container Params + /// The maximum number of bytes to pass to the container params. + pub max_container_params_len: u32, + /// Hash of the serialized container_params to prevent RPC tampering. + /// Should be verified within your function to ensure you are using the correct parameters. + pub container_params_hash: [u8; 32], + /// The stringified container params to pass to the function. + pub container_params: Vec, + + // Metadata + /// The unix timestamp when the function was created. + pub created_at: i64, + /// The slot when the account can be garbage collected and closed by anyone for a portion of the rent. + pub garbage_collection_slot: Option, + + /// The last recorded error code if most recent response was an error. + pub error_status: u8, + + /// Reserved. + pub _ebuf: [u8; 255], +} +impl Default for FunctionRequestAccountData { + fn default() -> Self { + Self { + is_triggered: 0, + status: RequestStatus::None, + authority: Pubkey::default(), + payer: Pubkey::default(), + function: Pubkey::default(), + escrow: Pubkey::default(), + attestation_queue: Pubkey::default(), + active_request: FunctionRequestTriggerRound::default(), + previous_request: FunctionRequestTriggerRound::default(), + max_container_params_len: 0, + container_params_hash: [0u8; 32], + container_params: Vec::new(), + created_at: 0, + garbage_collection_slot: None, + error_status: 0, + _ebuf: [0u8; 255], + } + } +} + +impl anchor_lang::AccountSerialize for FunctionRequestAccountData { + fn try_serialize(&self, writer: &mut W) -> anchor_lang::Result<()> { + if writer + .write_all(&FunctionRequestAccountData::discriminator()) + .is_err() + { + return Err(anchor_lang::error::ErrorCode::AccountDidNotSerialize.into()); + } + if AnchorSerialize::serialize(self, writer).is_err() { + return Err(anchor_lang::error::ErrorCode::AccountDidNotSerialize.into()); + } + Ok(()) + } +} + +impl anchor_lang::AccountDeserialize for FunctionRequestAccountData { + fn try_deserialize(buf: &mut &[u8]) -> anchor_lang::Result { + if buf.len() < FunctionRequestAccountData::discriminator().len() { + return Err(anchor_lang::error::ErrorCode::AccountDiscriminatorNotFound.into()); + } + let given_disc = &buf[..8]; + if FunctionRequestAccountData::discriminator() != given_disc { + return Err( + anchor_lang::error::Error::from(anchor_lang::error::AnchorError { + error_name: anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch.name(), + error_code_number: anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch + .into(), + error_msg: anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch + .to_string(), + error_origin: Some(anchor_lang::error::ErrorOrigin::Source( + anchor_lang::error::Source { + filename: "programs/attestation_program/src/lib.rs", + line: 1u32, + }, + )), + compared_values: None, + }) + .with_account_name("FunctionRequestAccountData"), + ); + } + Self::try_deserialize_unchecked(buf) + } + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + let mut data: &[u8] = &buf[8..]; + AnchorDeserialize::deserialize(&mut data) + .map_err(|_| anchor_lang::error::ErrorCode::AccountDidNotDeserialize.into()) + } +} + +impl Discriminator for FunctionRequestAccountData { + const DISCRIMINATOR: [u8; 8] = [8, 14, 177, 85, 144, 65, 148, 246]; +} + +impl Owner for FunctionRequestAccountData { + fn owner() -> Pubkey { + SWITCHBOARD_ATTESTATION_PROGRAM_ID + } +} + +impl FunctionRequestAccountData { + pub fn space(len: Option) -> usize { + let base: usize = 8 // discriminator + + get_instance_packed_len(&FunctionRequestAccountData::default()).unwrap(); + let vec_elements: usize = len.unwrap_or(crate::DEFAULT_MAX_CONTAINER_PARAMS_LEN) as usize; + base + vec_elements + } + + // verify if their is a non-expired pending request + pub fn is_round_active(&self, clock: &Clock) -> bool { + // 1. check status enum + if !self.active_request.status.is_active() { + return false; + } + + // 2. check valid after slot + // TODO: we should throw a more descriptive error for this + if clock.slot < self.active_request.valid_after_slot { + return false; + } + + // 3. check expiration + if self.active_request.expiration_slot > 0 + && clock.slot >= self.active_request.expiration_slot + { + return false; + } + + true + } + + /// Validates the given `signer` account against the `function_account_info` and the `active_request` + /// stored in this `FunctionRequestAccountData`. + /// + /// # Arguments + /// + /// * `function_account_info` - The `AccountInfo` of the function account. + /// * `signer` - The `AccountInfo` of the account to validate. + /// + /// # Errors + /// + /// Returns an error if the function account data cannot be loaded or if the `signer` account does not match + /// the expected `enclave_signer` stored in the `active_request`. + /// + /// # Returns + /// + /// Returns `Ok(true)` if the validation succeeds, `Ok(false)` otherwise. + /// + /// # Examples + /// + /// ```ignore + /// use switchboard_solana::FunctionRequestAccountData; + /// + /// #[derive(Accounts)] + /// pub struct Settle<'info> { + /// // YOUR PROGRAM ACCOUNTS + /// #[account( + /// mut, + /// has_one = switchboard_request, + /// )] + /// pub user: AccountLoader<'info, UserState>, + /// + /// // SWITCHBOARD ACCOUNTS + /// pub switchboard_function: AccountLoader<'info, FunctionAccountData>, + /// #[account( + /// constraint = switchboard_request.validate_signer( + /// &switchboard_function.to_account_info(), + /// &enclave_signer.to_account_info() + /// )? + /// )] + /// pub switchboard_request: Box>, + /// pub enclave_signer: Signer<'info>, + /// } + /// ``` + pub fn validate_signer<'a>( + &self, + function_account_info: &'a AccountInfo<'a>, + signer: &AccountInfo<'a>, + ) -> anchor_lang::Result { + if self.function != function_account_info.key() { + msg!( + "FunctionMismatch: expected {}, received {}", + self.function, + function_account_info.key() + ); + return Ok(false); + } + + let function_loader = + AccountLoader::<'_, FunctionAccountData>::try_from(function_account_info)?; + function_loader.load()?; // check owner/discriminator + + // validate the enclaves delegated signer matches + if self.active_request.enclave_signer != signer.key() { + msg!( + "SignerMismatch: expected {}, received {}", + self.active_request.enclave_signer, + signer.key() + ); + return Ok(false); + } + + Ok(true) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use std::str::FromStr; + + const REQUEST_DATA: [u8; 1309] = [ + 8, 14, 177, 85, 144, 65, 148, 246, 0, 4, 191, 163, 95, 149, 251, 196, 61, 38, 170, 30, 192, + 210, 238, 210, 121, 251, 115, 80, 136, 183, 116, 88, 7, 195, 127, 225, 4, 177, 167, 250, + 214, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 200, 91, 33, 133, 251, 77, 4, 45, 33, 88, 160, 219, 74, 253, 191, 56, 191, + 52, 130, 87, 44, 197, 78, 47, 64, 1, 9, 49, 23, 46, 248, 118, 67, 254, 215, 187, 179, 81, + 198, 84, 39, 244, 16, 113, 89, 56, 41, 133, 66, 71, 68, 238, 198, 34, 226, 219, 65, 150, + 252, 243, 229, 140, 153, 112, 174, 177, 70, 231, 73, 196, 214, 194, 190, 219, 159, 24, 162, + 119, 159, 16, 120, 53, 239, 102, 225, 241, 66, 97, 108, 144, 152, 47, 53, 76, 242, 215, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 212, 153, 154, 14, 0, 0, 0, 0, 225, 153, 154, 14, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 214, 176, 30, 24, 236, 238, 245, 97, 218, 201, 34, 20, 25, 94, 235, 88, + 235, 48, 114, 193, 144, 126, 220, 233, 142, 238, 32, 191, 233, 220, 175, 23, 80, 233, 228, + 192, 87, 36, 180, 107, 5, 182, 70, 125, 89, 139, 68, 5, 118, 218, 209, 167, 207, 52, 20, + 76, 217, 241, 92, 50, 106, 53, 253, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 159, 54, 102, 77, 67, 235, 26, 94, 144, 172, 18, 65, 45, 54, 127, 59, 100, 213, 206, + 91, 40, 101, 248, 189, 195, 19, 165, 190, 123, 227, 54, 103, 125, 0, 0, 0, 80, 73, 68, 61, + 69, 53, 77, 65, 115, 122, 106, 122, 56, 113, 90, 90, 68, 72, 75, 113, 81, 50, 49, 103, 53, + 119, 89, 117, 104, 77, 84, 106, 77, 98, 107, 49, 76, 52, 76, 52, 106, 66, 70, 88, 77, 103, + 113, 71, 44, 77, 73, 78, 95, 82, 69, 83, 85, 76, 84, 61, 49, 44, 77, 65, 88, 95, 82, 69, + 83, 85, 76, 84, 61, 49, 48, 44, 85, 83, 69, 82, 61, 68, 117, 53, 77, 111, 52, 89, 70, 70, + 70, 76, 113, 84, 57, 75, 90, 81, 75, 80, 77, 119, 52, 67, 109, 101, 111, 53, 86, 102, 71, + 76, 117, 114, 106, 99, 82, 104, 120, 104, 98, 51, 112, 106, 75, 130, 192, 8, 101, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + + const REQUEST_DATA_HEX: &str = "080eb155904194f60004bfa35f95fbc43d26aa1ec0d2eed279fb735088b7745807c37fe104b1a7fad6620000000000000000000000000000000000000000000000000000000000000000c85b2185fb4d042d2158a0db4afdbf38bf3482572cc54e2f40010931172ef87643fed7bbb351c65427f4107159382985424744eec622e2db4196fcf3e58c9970aeb146e749c4d6c2bedb9f18a2779f107835ef66e1f142616c90982f354cf2d7040000000000000000d4999a0e00000000e1999a0e000000000000000000000000d6b01e18eceef561dac92214195eeb58eb3072c1907edce98eee20bfe9dcaf1750e9e4c05724b46b05b6467d598b440576dad1a7cf34144cd9f15c326a35fd3c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200009f36664d43eb1a5e90ac12412d367f3b64d5ce5b2865f8bdc313a5be7be336677d0000005049443d45354d41737a6a7a38715a5a44484b715132316735775975684d546a4d626b314c344c346a4246584d6771472c4d494e5f524553554c543d312c4d41585f524553554c543d31302c555345523d4475354d6f34594646464c7154394b5a514b504d7734436d656f355666474c75726a63526878686233706a4b82c00865000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + + const EXPECTED_CONTAINER_PARAMS: &str = "PID=E5MAszjz8qZZDHKqQ21g5wYuhMTjMbk1L4L4jBFXMgqG,MIN_RESULT=1,MAX_RESULT=10,USER=Du5Mo4YFFFLqT9KZQKPMw4Cmeo5VfGLurjcRhxhb3pjK"; + + #[test] + fn test_request_deserialization() { + let request = + FunctionRequestAccountData::try_deserialize_unchecked(&mut REQUEST_DATA.as_slice()) + .unwrap(); + + let container_params = std::str::from_utf8(&request.container_params) + .unwrap() + .to_string(); + + assert_eq!(container_params, EXPECTED_CONTAINER_PARAMS.to_string()); + assert_eq!( + request.function, + Pubkey::from_str("EV78uGX5CKioM7MyY8tY1nQFJtNXnjVGTCV2tamWdXGh").unwrap() + ); + assert_eq!( + request.escrow, + Pubkey::from_str("5aRhbaGeoe7HTwoMwGgeENGXuVCLcRBNxFrmFnWGG1bM").unwrap() + ); + } + + #[test] + fn test_hex_decode() { + let account_bytes = hex::decode(REQUEST_DATA_HEX).unwrap(); + let request = + FunctionRequestAccountData::try_deserialize(&mut account_bytes.as_slice()).unwrap(); + + let container_params = std::str::from_utf8(&request.container_params) + .unwrap() + .to_string(); + + assert_eq!(container_params, EXPECTED_CONTAINER_PARAMS.to_string()); + + assert_eq!( + request.function, + Pubkey::from_str("EV78uGX5CKioM7MyY8tY1nQFJtNXnjVGTCV2tamWdXGh").unwrap() + ); + assert_eq!( + request.escrow, + Pubkey::from_str("5aRhbaGeoe7HTwoMwGgeENGXuVCLcRBNxFrmFnWGG1bM").unwrap() + ); + } + + #[test] + fn test_hex_encode() { + // Encode the bytes a hex value + let request = + FunctionRequestAccountData::try_deserialize(&mut REQUEST_DATA.as_slice()).unwrap(); + let request_data = [ + &FunctionRequestAccountData::DISCRIMINATOR[..], + &request.try_to_vec().unwrap()[..], + ] + .concat(); + + // Decode the serialized bytes + let decoded_request = + FunctionRequestAccountData::try_deserialize(&mut request_data.as_slice()).unwrap(); + + assert_eq!(request.created_at, decoded_request.created_at); + assert_eq!( + request.container_params.len(), + decoded_request.container_params.len() + ); + } +} diff --git a/rust/switchboard-solana/src/attestation_program/accounts/request.rs b/rust/switchboard-solana/src/attestation_program/accounts/request.rs index 4e4d3b25e..29176a368 100644 --- a/rust/switchboard-solana/src/attestation_program/accounts/request.rs +++ b/rust/switchboard-solana/src/attestation_program/accounts/request.rs @@ -1,5 +1,5 @@ -use crate::{cfg_client, prelude::*}; -use solana_program::borsh0_10::get_instance_packed_len; +use crate::prelude::*; +use solana_program::borsh::get_instance_packed_len; #[repr(u8)] #[derive(Copy, Clone, Default, Debug, Eq, PartialEq, AnchorSerialize, AnchorDeserialize)] @@ -12,6 +12,11 @@ pub enum RequestStatus { RequestExpired = 4, RequestSuccess = 5, } +impl RequestStatus { + pub fn is_active(&self) -> bool { + matches!(self, RequestStatus::RequestPending) + } +} impl From for u8 { fn from(value: RequestStatus) -> Self { match value { @@ -37,7 +42,17 @@ impl From for RequestStatus { } } -#[derive(Copy, Clone, AnchorDeserialize, AnchorSerialize, PartialEq)] +fn serialize_slice( + slice: &[T], + writer: &mut W, +) -> std::result::Result<(), std::io::Error> { + for item in slice { + item.serialize(writer)?; + } + Ok(()) +} + +#[derive(Copy, Clone, PartialEq)] pub struct FunctionRequestTriggerRound { /// The status of the request. pub status: RequestStatus, @@ -58,70 +73,100 @@ pub struct FunctionRequestTriggerRound { /// The slot when the request can first be executed. pub valid_after_slot: u64, + /// The index of the verifier assigned to this request. + pub queue_idx: u32, + /// Reserved. - pub _ebuf: [u8; 56], + pub _ebuf: [u8; 52], } impl Default for FunctionRequestTriggerRound { fn default() -> Self { unsafe { std::mem::zeroed() } } } -// impl borsh::ser::BorshSerialize for FunctionRequestTriggerRound -// where -// RequestStatus: borsh::ser::BorshSerialize, -// u64: borsh::ser::BorshSerialize, -// u64: borsh::ser::BorshSerialize, -// u64: borsh::ser::BorshSerialize, -// u64: borsh::ser::BorshSerialize, -// Pubkey: borsh::ser::BorshSerialize, -// Pubkey: borsh::ser::BorshSerialize, -// u64: borsh::ser::BorshSerialize, -// { -// fn serialize( -// &self, -// writer: &mut W, -// ) -> ::core::result::Result<(), borsh::maybestd::io::Error> { -// borsh::BorshSerialize::serialize(&self.status, writer)?; -// borsh::BorshSerialize::serialize(&self.bounty, writer)?; -// borsh::BorshSerialize::serialize(&self.request_slot, writer)?; -// borsh::BorshSerialize::serialize(&self.fulfilled_slot, writer)?; -// borsh::BorshSerialize::serialize(&self.expiration_slot, writer)?; -// borsh::BorshSerialize::serialize(&self.verifier, writer)?; -// borsh::BorshSerialize::serialize(&self.enclave_signer, writer)?; -// borsh::BorshSerialize::serialize(&self.valid_after_slot, writer)?; -// writer.write_all(&[0u8; 56])?; -// // borsh::BorshSerialize::serialize(&[0u8; 56], writer)?; -// Ok(()) -// } -// } -// impl borsh::de::BorshDeserialize for FunctionRequestTriggerRound -// where -// RequestStatus: borsh::BorshDeserialize, -// u64: borsh::BorshDeserialize, -// u64: borsh::BorshDeserialize, -// u64: borsh::BorshDeserialize, -// u64: borsh::BorshDeserialize, -// Pubkey: borsh::BorshDeserialize, -// Pubkey: borsh::BorshDeserialize, -// u64: borsh::BorshDeserialize, -// { -// fn deserialize(buf: &mut &[u8]) -> ::core::result::Result { -// Ok(Self { -// status: borsh::BorshDeserialize::deserialize(buf)?, -// bounty: borsh::BorshDeserialize::deserialize(buf)?, -// request_slot: borsh::BorshDeserialize::deserialize(buf)?, -// fulfilled_slot: borsh::BorshDeserialize::deserialize(buf)?, -// expiration_slot: borsh::BorshDeserialize::deserialize(buf)?, -// verifier: borsh::BorshDeserialize::deserialize(buf)?, -// enclave_signer: borsh::BorshDeserialize::deserialize(buf)?, -// valid_after_slot: borsh::BorshDeserialize::deserialize(buf)?, -// _ebuf: [0u8; 56], -// }) -// } -// } + +fn deserialize_round_ebuf_slice( + reader: &mut R, +) -> std::result::Result<[u8; 52], std::io::Error> { + let mut buffer = [0u8; 52]; + reader.read_exact(&mut buffer)?; + Ok(buffer) +} + +impl borsh::ser::BorshSerialize for FunctionRequestTriggerRound +where + RequestStatus: borsh::ser::BorshSerialize, + u64: borsh::ser::BorshSerialize, + u64: borsh::ser::BorshSerialize, + u64: borsh::ser::BorshSerialize, + u64: borsh::ser::BorshSerialize, + Pubkey: borsh::ser::BorshSerialize, + Pubkey: borsh::ser::BorshSerialize, + u64: borsh::ser::BorshSerialize, +{ + fn serialize( + &self, + writer: &mut W, + ) -> ::core::result::Result<(), borsh::maybestd::io::Error> { + borsh::BorshSerialize::serialize(&self.status, writer)?; + borsh::BorshSerialize::serialize(&self.bounty, writer)?; + borsh::BorshSerialize::serialize(&self.request_slot, writer)?; + borsh::BorshSerialize::serialize(&self.fulfilled_slot, writer)?; + borsh::BorshSerialize::serialize(&self.expiration_slot, writer)?; + borsh::BorshSerialize::serialize(&self.verifier, writer)?; + borsh::BorshSerialize::serialize(&self.enclave_signer, writer)?; + borsh::BorshSerialize::serialize(&self.valid_after_slot, writer)?; + borsh::BorshSerialize::serialize(&self.queue_idx, writer)?; + serialize_slice(&self._ebuf, writer)?; + Ok(()) + } +} +impl borsh::de::BorshDeserialize for FunctionRequestTriggerRound +where + RequestStatus: borsh::BorshDeserialize, + u64: borsh::BorshDeserialize, + u64: borsh::BorshDeserialize, + u64: borsh::BorshDeserialize, + u64: borsh::BorshDeserialize, + Pubkey: borsh::BorshDeserialize, + Pubkey: borsh::BorshDeserialize, + u64: borsh::BorshDeserialize, +{ + // fn deserialize(buf: &mut &[u8]) -> ::core::result::Result { + // Ok(Self { + // status: borsh::BorshDeserialize::deserialize(buf)?, + // bounty: borsh::BorshDeserialize::deserialize(buf)?, + // request_slot: borsh::BorshDeserialize::deserialize(buf)?, + // fulfilled_slot: borsh::BorshDeserialize::deserialize(buf)?, + // expiration_slot: borsh::BorshDeserialize::deserialize(buf)?, + // verifier: borsh::BorshDeserialize::deserialize(buf)?, + // enclave_signer: borsh::BorshDeserialize::deserialize(buf)?, + // valid_after_slot: borsh::BorshDeserialize::deserialize(buf)?, + // queue_idx: borsh::BorshDeserialize::deserialize(buf)?, + // _ebuf: deserialize_round_ebuf_slice(buf)?, + // }) + // } + + fn deserialize_reader( + reader: &mut R, + ) -> ::core::result::Result { + Ok(Self { + status: borsh::BorshDeserialize::deserialize_reader(reader)?, + bounty: borsh::BorshDeserialize::deserialize_reader(reader)?, + request_slot: borsh::BorshDeserialize::deserialize_reader(reader)?, + fulfilled_slot: borsh::BorshDeserialize::deserialize_reader(reader)?, + expiration_slot: borsh::BorshDeserialize::deserialize_reader(reader)?, + verifier: borsh::BorshDeserialize::deserialize_reader(reader)?, + enclave_signer: borsh::BorshDeserialize::deserialize_reader(reader)?, + valid_after_slot: borsh::BorshDeserialize::deserialize_reader(reader)?, + queue_idx: borsh::BorshDeserialize::deserialize_reader(reader)?, + _ebuf: borsh::BorshDeserialize::deserialize_reader(reader)?, + }) + } +} // #[account] -#[derive(AnchorDeserialize, AnchorSerialize, Clone, PartialEq)] +#[derive(Clone, PartialEq)] pub struct FunctionRequestAccountData { // Up-Front Params for RPC filtering /// Whether the request is ready to be processed. @@ -191,6 +236,107 @@ impl Default for FunctionRequestAccountData { } } +fn deserialize_ebuf_slice( + reader: &mut R, +) -> std::result::Result<[u8; 255], std::io::Error> { + let mut buffer = [0u8; 255]; + reader.read_exact(&mut buffer)?; + Ok(buffer) +} + +impl borsh::ser::BorshSerialize for FunctionRequestAccountData +where + RequestStatus: borsh::ser::BorshSerialize, + u64: borsh::ser::BorshSerialize, + u64: borsh::ser::BorshSerialize, + u64: borsh::ser::BorshSerialize, + u64: borsh::ser::BorshSerialize, + Pubkey: borsh::ser::BorshSerialize, + Pubkey: borsh::ser::BorshSerialize, + u64: borsh::ser::BorshSerialize, + FunctionRequestTriggerRound: borsh::ser::BorshSerialize, + Vec: borsh::ser::BorshSerialize, +{ + fn serialize( + &self, + writer: &mut W, + ) -> ::core::result::Result<(), borsh::maybestd::io::Error> { + borsh::BorshSerialize::serialize(&self.is_triggered, writer)?; + borsh::BorshSerialize::serialize(&self.status, writer)?; + borsh::BorshSerialize::serialize(&self.authority, writer)?; + borsh::BorshSerialize::serialize(&self.payer, writer)?; + borsh::BorshSerialize::serialize(&self.function, writer)?; + borsh::BorshSerialize::serialize(&self.escrow, writer)?; + borsh::BorshSerialize::serialize(&self.attestation_queue, writer)?; + borsh::BorshSerialize::serialize(&self.active_request, writer)?; + borsh::BorshSerialize::serialize(&self.previous_request, writer)?; + borsh::BorshSerialize::serialize(&self.max_container_params_len, writer)?; + borsh::BorshSerialize::serialize(&self.container_params_hash, writer)?; + borsh::BorshSerialize::serialize(&self.container_params, writer)?; + borsh::BorshSerialize::serialize(&self.created_at, writer)?; + borsh::BorshSerialize::serialize(&self.garbage_collection_slot, writer)?; + borsh::BorshSerialize::serialize(&self.error_status, writer)?; + serialize_slice(&self._ebuf, writer)?; + Ok(()) + } +} +impl borsh::de::BorshDeserialize for FunctionRequestAccountData +where + RequestStatus: borsh::BorshDeserialize, + u64: borsh::BorshDeserialize, + u64: borsh::BorshDeserialize, + u64: borsh::BorshDeserialize, + u64: borsh::BorshDeserialize, + Pubkey: borsh::BorshDeserialize, + Pubkey: borsh::BorshDeserialize, + u64: borsh::BorshDeserialize, + FunctionRequestTriggerRound: borsh::BorshDeserialize, +{ + // fn deserialize(buf: &mut &[u8]) -> ::core::result::Result { + // Ok(Self { + // is_triggered: borsh::BorshDeserialize::deserialize(buf)?, + // status: borsh::BorshDeserialize::deserialize(buf)?, + // authority: borsh::BorshDeserialize::deserialize(buf)?, + // payer: borsh::BorshDeserialize::deserialize(buf)?, + // function: borsh::BorshDeserialize::deserialize(buf)?, + // escrow: borsh::BorshDeserialize::deserialize(buf)?, + // attestation_queue: borsh::BorshDeserialize::deserialize(buf)?, + // active_request: borsh::BorshDeserialize::deserialize(buf)?, + // previous_request: borsh::BorshDeserialize::deserialize(buf)?, + // max_container_params_len: borsh::BorshDeserialize::deserialize(buf)?, + // container_params_hash: borsh::BorshDeserialize::deserialize(buf)?, + // container_params: borsh::BorshDeserialize::deserialize(buf)?, + // created_at: borsh::BorshDeserialize::deserialize(buf)?, + // garbage_collection_slot: borsh::BorshDeserialize::deserialize(buf)?, + // error_status: borsh::BorshDeserialize::deserialize(buf)?, + // _ebuf: deserialize_ebuf_slice(buf)?, + // }) + // } + + fn deserialize_reader( + reader: &mut R, + ) -> ::core::result::Result { + Ok(Self { + is_triggered: borsh::BorshDeserialize::deserialize_reader(reader)?, + status: borsh::BorshDeserialize::deserialize_reader(reader)?, + authority: borsh::BorshDeserialize::deserialize_reader(reader)?, + payer: borsh::BorshDeserialize::deserialize_reader(reader)?, + function: borsh::BorshDeserialize::deserialize_reader(reader)?, + escrow: borsh::BorshDeserialize::deserialize_reader(reader)?, + attestation_queue: borsh::BorshDeserialize::deserialize_reader(reader)?, + active_request: borsh::BorshDeserialize::deserialize_reader(reader)?, + previous_request: borsh::BorshDeserialize::deserialize_reader(reader)?, + max_container_params_len: borsh::BorshDeserialize::deserialize_reader(reader)?, + container_params_hash: borsh::BorshDeserialize::deserialize_reader(reader)?, + container_params: borsh::BorshDeserialize::deserialize_reader(reader)?, + created_at: borsh::BorshDeserialize::deserialize_reader(reader)?, + garbage_collection_slot: borsh::BorshDeserialize::deserialize_reader(reader)?, + error_status: borsh::BorshDeserialize::deserialize_reader(reader)?, + _ebuf: borsh::BorshDeserialize::deserialize_reader(reader)?, + }) + } +} + impl anchor_lang::AccountSerialize for FunctionRequestAccountData { fn try_serialize(&self, writer: &mut W) -> anchor_lang::Result<()> { if writer @@ -254,46 +400,99 @@ impl FunctionRequestAccountData { pub fn space(len: Option) -> usize { let base: usize = 8 // discriminator + get_instance_packed_len(&FunctionRequestAccountData::default()).unwrap(); - let vec_elements: usize = len.unwrap_or(crate::DEFAULT_USERS_CONTAINER_PARAMS_LEN) as usize; + let vec_elements: usize = len.unwrap_or(crate::DEFAULT_MAX_CONTAINER_PARAMS_LEN) as usize; base + vec_elements } // verify if their is a non-expired pending request pub fn is_round_active(&self, clock: &Clock) -> bool { - if self.active_request.status == RequestStatus::RequestPending - && self.active_request.expiration_slot > 0 + // 1. check status enum + if !self.active_request.status.is_active() { + return false; + } + + // 2. check valid after slot + // TODO: we should throw a more descriptive error for this + if clock.slot < self.active_request.valid_after_slot { + return false; + } + + // 3. check expiration + if self.active_request.expiration_slot > 0 && clock.slot >= self.active_request.expiration_slot { - return true; + return false; } - false + true } + /// Validates the given `signer` account against the `function_account_info` and the `active_request` + /// stored in this `FunctionRequestAccountData`. + /// + /// # Arguments + /// + /// * `function_account_info` - The `AccountInfo` of the function account. + /// * `signer` - The `AccountInfo` of the account to validate. + /// + /// # Errors + /// + /// Returns an error if the function account data cannot be loaded or if the `signer` account does not match + /// the expected `enclave_signer` stored in the `active_request`. + /// + /// # Returns + /// + /// Returns `Ok(true)` if the validation succeeds, `Ok(false)` otherwise. + /// + /// # Examples + /// + /// ```ignore + /// use switchboard_solana::FunctionRequestAccountData; + /// + /// #[derive(Accounts)] + /// pub struct Settle<'info> { + /// // YOUR PROGRAM ACCOUNTS + /// #[account( + /// mut, + /// has_one = switchboard_request, + /// )] + /// pub user: AccountLoader<'info, UserState>, + /// + /// // SWITCHBOARD ACCOUNTS + /// pub switchboard_function: AccountLoader<'info, FunctionAccountData>, + /// #[account( + /// constraint = switchboard_request.validate_signer( + /// &switchboard_function.to_account_info(), + /// &enclave_signer.to_account_info() + /// )? + /// )] + /// pub switchboard_request: Box>, + /// pub enclave_signer: Signer<'info>, + /// } + /// ``` pub fn validate_signer<'a>( &self, - function_account_info: &AccountInfo<'a>, + function_account_info: &'a AccountInfo<'a>, signer: &AccountInfo<'a>, ) -> anchor_lang::Result { - if self.function != function_account_info.key() { - msg!("function key mismatch"); + let function_loader = + AccountLoader::<'a, FunctionAccountData>::try_from(function_account_info)?; + + if self.function != function_loader.key() { msg!( - "expected {}, received {}", + "FunctionMismatch: expected {}, received {}", self.function, - function_account_info.key() + function_loader.key() ); return Ok(false); } - let function_loader = - AccountLoader::<'_, FunctionAccountData>::try_from(&function_account_info.clone())?; function_loader.load()?; // check owner/discriminator // validate the enclaves delegated signer matches if self.active_request.enclave_signer != signer.key() { - msg!("request signer mismatch"); msg!( - "expected {}, received {}", + "SignerMismatch: expected {}, received {}", self.active_request.enclave_signer, signer.key() ); @@ -302,52 +501,6 @@ impl FunctionRequestAccountData { Ok(true) } - - cfg_client! { - pub fn get_discriminator_filter() -> solana_client::rpc_filter::RpcFilterType { - solana_client::rpc_filter::RpcFilterType::Memcmp(solana_client::rpc_filter::Memcmp::new_raw_bytes( - 0, - FunctionRequestAccountData::discriminator().to_vec(), - )) - } - - pub fn get_is_triggered_filter() -> solana_client::rpc_filter::RpcFilterType { - solana_client::rpc_filter::RpcFilterType::Memcmp(solana_client::rpc_filter::Memcmp::new_raw_bytes( - 8, - vec![1u8], - )) - } - - pub fn get_is_active_filter() -> solana_client::rpc_filter::RpcFilterType { - solana_client::rpc_filter::RpcFilterType::Memcmp(solana_client::rpc_filter::Memcmp::new_raw_bytes( - 9, - vec![RequestStatus::RequestPending as u8], - )) - } - - pub fn get_queue_filter(queue_pubkey: &Pubkey) -> solana_client::rpc_filter::RpcFilterType { - solana_client::rpc_filter::RpcFilterType::Memcmp(solana_client::rpc_filter::Memcmp::new_raw_bytes( - 138, - queue_pubkey.to_bytes().into(), - )) - } - - pub fn get_is_ready_filters(queue_pubkey: &Pubkey) -> Vec { - vec![ - FunctionRequestAccountData::get_discriminator_filter(), - FunctionRequestAccountData::get_is_triggered_filter(), - FunctionRequestAccountData::get_is_active_filter(), - FunctionRequestAccountData::get_queue_filter(queue_pubkey), - ] - } - - pub async fn fetch( - client: &solana_client::rpc_client::RpcClient, - pubkey: Pubkey, - ) -> std::result::Result { - crate::client::fetch_anchor_account(client, pubkey).await - } - } } #[cfg(test)] @@ -423,9 +576,6 @@ mod tests { .unwrap() .to_string(); - println!("Max params Len: {}", request.max_container_params_len); - println!("Params Len: {}", request.container_params.len()); - assert_eq!(container_params, EXPECTED_CONTAINER_PARAMS.to_string()); assert_eq!( request.function, diff --git a/rust/switchboard-solana/src/attestation_program/accounts/routine.anchor28.rs b/rust/switchboard-solana/src/attestation_program/accounts/routine.anchor28.rs new file mode 100644 index 000000000..74fbf24f4 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/accounts/routine.anchor28.rs @@ -0,0 +1,381 @@ +use crate::prelude::*; +use crate::*; +use solana_program::borsh0_10::get_instance_packed_len; + +#[repr(u8)] +#[derive( + Copy, Clone, Default, Debug, Eq, PartialEq, AnchorSerialize, AnchorDeserialize, InitSpace, +)] +pub enum RoutineStatus { + #[default] + None = 0, // 0 + Active, + NonExecutable, +} +impl RoutineStatus { + pub fn is_active(&self) -> bool { + matches!(self, RoutineStatus::Active) + } +} +impl From for u8 { + fn from(value: RoutineStatus) -> Self { + match value { + RoutineStatus::Active => 1, + RoutineStatus::NonExecutable => 2, + _ => 0, + } + } +} +impl From for RoutineStatus { + fn from(value: u8) -> Self { + match value { + 1 => RoutineStatus::Active, + 2 => RoutineStatus::NonExecutable, + _ => RoutineStatus::default(), + } + } +} + +// #[account] +#[derive(AnchorDeserialize, AnchorSerialize, Debug, Clone, PartialEq)] +pub struct FunctionRoutineAccountData { + // Metadata (8) + /// The name of the function routine for easier identification. + pub name: [u8; 64], + /// The metadata of the function routine for easier identification. + pub metadata: [u8; 256], + /// The unix timestamp when the function routine was created. + pub created_at: i64, + /// The unix timestamp when the function routine config was changed. + pub updated_at: i64, + + // Disabled Config + /// Flag to disable the function and prevent new verification requests. + pub is_disabled: ResourceLevel, + /// The type of resource that disabled the routine. + // pub disabler: ResourceLevel, + + // Status + pub status: RoutineStatus, + /// The last reported error code if the most recent response was a failure + pub error_status: u8, + /// The enclave generated signer for this routine. + pub enclave_signer: Pubkey, + /// The verifier oracle who signed this verification. + pub verifier: Pubkey, + + // Fees + /// The SOL bounty in lamports used to incentivize a verifier to expedite the request. 0 = no bounty. Receiver = verifier oracle. + pub bounty: u64, + + // Accounts + /// Signer allowed to manage the routine. + pub authority: Pubkey, + /// The default destination for rent exemption when the account is closed. + pub payer: Pubkey, + /// The function that manages the mr_enclave set for this routine. + pub function: Pubkey, + /// The Attestation Queue for this request. + pub attestation_queue: Pubkey, + + /// The tokenAccount escrow + // The SwitchboardWallet that manages the escrow. A single SwitchboardWallet can support many routines. + pub escrow_wallet: Pubkey, + /// The TokenAccount with funds for the escrow. + pub escrow_token_wallet: Pubkey, + + // Execution Config + /// The index of the verifier on the queue that is assigned to process the next invocation. + /// This is incremented after each invocation in a round-robin fashion. + pub queue_idx: u32, + /// The cron schedule to run the function on. + pub schedule: [u8; 64], + // Container Params + /// The maximum number of bytes to pass to the container params. + pub max_container_params_len: u32, + /// Hash of the serialized container_params to prevent RPC tampering. + /// Should be verified within your function to ensure you are using the correct parameters. + pub container_params_hash: [u8; 32], + /// The stringified container params to pass to the function. + pub container_params: Vec, + + // Status / Tracking + /// The unix timestamp when the function was last run. + pub last_execution_timestamp: i64, + /// The unix timestamp when the function was last run successfully. + pub last_successful_execution_timestamp: i64, + /// The unix timestamp when the function is allowed to run next. + pub next_allowed_timestamp: i64, + + /// Reserved. + pub _ebuf: [u8; 512], +} +impl Default for FunctionRoutineAccountData { + fn default() -> Self { + Self { + // Metadata + name: [0u8; 64], + metadata: [0u8; 256], + created_at: 0, + updated_at: 0, + + // Disabled + is_disabled: ResourceLevel::None, + + // Status + status: RoutineStatus::None, + error_status: 0, + enclave_signer: Pubkey::default(), + verifier: Pubkey::default(), + + // Fees + bounty: 0, + + // Accounts + authority: Pubkey::default(), + payer: Pubkey::default(), + function: Pubkey::default(), + attestation_queue: Pubkey::default(), + + escrow_wallet: Pubkey::default(), + escrow_token_wallet: Pubkey::default(), + + // Execution + queue_idx: 0, + schedule: [0u8; 64], + max_container_params_len: 0, + container_params_hash: [0u8; 32], + container_params: vec![], + + // Status / Tracking + last_execution_timestamp: 0, + last_successful_execution_timestamp: 0, + next_allowed_timestamp: 0, + + // Reserved + _ebuf: [0u8; 512], + } + } +} + +impl anchor_lang::AccountSerialize for FunctionRoutineAccountData { + fn try_serialize(&self, writer: &mut W) -> anchor_lang::Result<()> { + if writer + .write_all(&FunctionRoutineAccountData::discriminator()) + .is_err() + { + return Err(anchor_lang::error::ErrorCode::AccountDidNotSerialize.into()); + } + if AnchorSerialize::serialize(self, writer).is_err() { + return Err(anchor_lang::error::ErrorCode::AccountDidNotSerialize.into()); + } + Ok(()) + } +} + +impl anchor_lang::AccountDeserialize for FunctionRoutineAccountData { + fn try_deserialize(buf: &mut &[u8]) -> anchor_lang::Result { + if buf.len() < FunctionRoutineAccountData::discriminator().len() { + return Err(anchor_lang::error::ErrorCode::AccountDiscriminatorNotFound.into()); + } + let given_disc = &buf[..8]; + if FunctionRoutineAccountData::discriminator() != given_disc { + return Err( + anchor_lang::error::Error::from(anchor_lang::error::AnchorError { + error_name: anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch.name(), + error_code_number: anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch + .into(), + error_msg: anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch + .to_string(), + error_origin: Some(anchor_lang::error::ErrorOrigin::Source( + anchor_lang::error::Source { + filename: "programs/attestation_program/src/lib.rs", + line: 1u32, + }, + )), + compared_values: None, + }) + .with_account_name("FunctionRoutineAccountData"), + ); + } + Self::try_deserialize_unchecked(buf) + } + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + let mut data: &[u8] = &buf[8..]; + AnchorDeserialize::deserialize(&mut data) + .map_err(|_| anchor_lang::error::ErrorCode::AccountDidNotDeserialize.into()) + } +} + +impl Discriminator for FunctionRoutineAccountData { + const DISCRIMINATOR: [u8; 8] = [93, 99, 13, 119, 129, 127, 168, 18]; +} + +impl Owner for FunctionRoutineAccountData { + fn owner() -> Pubkey { + SWITCHBOARD_ATTESTATION_PROGRAM_ID + } +} + +impl FunctionRoutineAccountData { + /// Returns the amount of memory space required for a FunctionRoutine account. + /// + /// # Arguments + /// + /// * `len` - An optional `u32` value representing the length of the container parameters vector. + /// + /// # Returns + /// + /// * `usize` - The total amount of memory space required for a FunctionRoutine account. + pub fn space(len: Option) -> usize { + // size of struct if vec is empty + let base: usize = get_instance_packed_len(&FunctionRoutineAccountData::default()).unwrap(); + msg!("FunctionRoutine base usize: {:?}", base); + // let base: usize = 1216; + + // the number of bytes needed for the container params + let vec_elements: usize = len.unwrap_or(DEFAULT_MAX_CONTAINER_PARAMS_LEN) as usize; + + // total bytes + 8 + base + vec_elements + } + + /// Asserts that the length of the account data matches the expected length. + /// + /// # Arguments + /// + /// * `account_info` - The account info to check the data length of. + /// * `len` - The expected length of the account data. + /// + /// # Errors + /// + /// Returns an error if the length of the account data does not match the expected length. + pub fn assert_data_len(account_info: &AccountInfo<'_>, len: Option) -> bool { + let data_len = account_info.data_len(); + // msg!("data_len: {:?}", data_len); + let expected_data_len = Self::space(len); + // msg!("expected_data_len: {:?}", expected_data_len); + + data_len == expected_data_len + + // if data_len != expected_data_len { + // return Err(error!(SwitchboardError::IllegalExecuteAttempt)); + // } + + // Ok(()) + } + + /// Checks if the schedule is empty by reading the first byte. + /// + /// # Returns + /// + /// A boolean indicating whether the schedule is empty or not. + pub fn is_empty_schedule(&self) -> bool { + self.schedule + .first() + .map(|&byte| byte == 0) + .unwrap_or(false) + } + + /// Returns a bool representing whether the routine is disabled for use. + pub fn is_disabled(&self) -> bool { + self.is_disabled.into() + } + + /// Validates the given `signer` account against the `function_account_info` and the enclave_signer + /// stored in this `FunctionRoutineAccountData`. + /// + /// # Arguments + /// + /// * `function_account_info` - The `AccountInfo` of the function account. + /// * `signer` - The `AccountInfo` of the account to validate. + /// + /// # Errors + /// + /// Returns an error if the function account data cannot be loaded or if the `signer` account does not match + /// the expected `enclave_signer`. + /// + /// # Returns + /// + /// Returns `Ok(true)` if the validation succeeds, `Ok(false)` otherwise. + /// + /// # Examples + /// + /// ```ignore + /// use switchboard_solana::FunctionRoutineAccountData; + /// + /// #[derive(Accounts)] + /// pub struct Settle<'info> { + /// // YOUR PROGRAM ACCOUNTS + /// #[account( + /// mut, + /// has_one = switchboard_routine, + /// )] + /// pub user: AccountLoader<'info, UserState>, + /// + /// // SWITCHBOARD ACCOUNTS + /// pub switchboard_function: AccountLoader<'info, FunctionAccountData>, + /// #[account( + /// constraint = switchboard_routine.validate_signer( + /// &switchboard_function.to_account_info(), + /// &enclave_signer.to_account_info() + /// )? + /// )] + /// pub switchboard_routine: Box>, + /// pub enclave_signer: Signer<'info>, + /// } + /// ``` + pub fn validate_signer<'a>( + &self, + function_account_info: &'a AccountInfo<'a>, + signer: &AccountInfo<'a>, + ) -> anchor_lang::Result { + if self.function != function_account_info.key() { + msg!( + "FunctionMismatch: expected {}, received {}", + self.function, + function_account_info.key() + ); + return Ok(false); + } + + let function_loader = + AccountLoader::<'_, FunctionAccountData>::try_from(function_account_info)?; + let func = function_loader.load()?; // check owner/discriminator + + if self.attestation_queue != func.attestation_queue { + msg!( + "QueueMismatch: expected {}, received {}", + self.attestation_queue, + func.attestation_queue + ); + return Ok(false); + } + + // validate the enclaves delegated signer matches + if self.enclave_signer != signer.key() { + msg!( + "SignerMismatch: expected {}, received {}", + self.enclave_signer, + signer.key() + ); + return Ok(false); + } + + Ok(true) + } + + pub fn get_name(&self) -> String { + std::str::from_utf8(&self.name) + .unwrap_or("") + .trim() + .to_string() + } + + pub fn get_metadata(&self) -> String { + std::str::from_utf8(&self.metadata) + .unwrap_or("") + .trim() + .to_string() + } +} diff --git a/rust/switchboard-solana/src/attestation_program/accounts/routine.rs b/rust/switchboard-solana/src/attestation_program/accounts/routine.rs new file mode 100644 index 000000000..2117993a0 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/accounts/routine.rs @@ -0,0 +1,386 @@ +use crate::prelude::*; +use crate::*; +use solana_program::borsh::get_instance_packed_len; + +#[repr(u8)] +#[derive( + Copy, Clone, Default, Debug, Eq, PartialEq, AnchorSerialize, AnchorDeserialize, InitSpace, +)] +pub enum RoutineStatus { + #[default] + None = 0, // 0 + Active, + NonExecutable, +} +impl RoutineStatus { + pub fn is_active(&self) -> bool { + matches!(self, RoutineStatus::Active) + } +} +impl From for u8 { + fn from(value: RoutineStatus) -> Self { + match value { + RoutineStatus::Active => 1, + RoutineStatus::NonExecutable => 2, + _ => 0, + } + } +} +impl From for RoutineStatus { + fn from(value: u8) -> Self { + match value { + 1 => RoutineStatus::Active, + 2 => RoutineStatus::NonExecutable, + _ => RoutineStatus::default(), + } + } +} + +// #[account] +#[derive(AnchorDeserialize, AnchorSerialize, Clone, PartialEq)] +pub struct FunctionRoutineAccountData { + // Metadata (8) + /// The name of the function routine for easier identification. + pub name: [u8; 64], + /// The metadata of the function routine for easier identification. + pub metadata: [u8; 256], + /// The unix timestamp when the function routine was created. + pub created_at: i64, + /// The unix timestamp when the function routine config was changed. + pub updated_at: i64, + + // 344 + + // Disabled Config + /// Flag to disable the function and prevent new verification requests. + pub is_disabled: ResourceLevel, + /// The type of resource that disabled the routine. + // pub disabler: ResourceLevel, + + // Status + pub status: RoutineStatus, + /// The last reported error code if the most recent response was a failure + pub error_status: u8, + /// The enclave generated signer for this routine. + pub enclave_signer: Pubkey, + /// The verifier oracle who signed this verification. + pub verifier: Pubkey, + + // Fees + /// The SOL bounty in lamports used to incentivize a verifier to expedite the request. 0 = no bounty. Receiver = verifier oracle. + pub bounty: u64, + + // 419 + + // Accounts + /// Signer allowed to manage the routine. + pub authority: Pubkey, + /// The default destination for rent exemption when the account is closed. + pub payer: Pubkey, + /// The function that manages the mr_enclave set for this routine. + pub function: Pubkey, + /// The Attestation Queue for this request. + pub attestation_queue: Pubkey, // 515 + + /// The tokenAccount escrow + // The SwitchboardWallet that manages the escrow. A single SwitchboardWallet can support many routines. + pub escrow_wallet: Pubkey, + /// The TokenAccount with funds for the escrow. + pub escrow_token_wallet: Pubkey, + + // Execution Config + /// The index of the verifier on the queue that is assigned to process the next invocation. + /// This is incremented after each invocation in a round-robin fashion. + pub queue_idx: u32, + /// The cron schedule to run the function on. + pub schedule: [u8; 64], + // Container Params + /// The maximum number of bytes to pass to the container params. + pub max_container_params_len: u32, + /// Hash of the serialized container_params to prevent RPC tampering. + /// Should be verified within your function to ensure you are using the correct parameters. + pub container_params_hash: [u8; 32], + /// The stringified container params to pass to the function. + pub container_params: Vec, + + // Status / Tracking + /// The unix timestamp when the function was last run. + pub last_execution_timestamp: i64, + /// The unix timestamp when the function was last run successfully. + pub last_successful_execution_timestamp: i64, + /// The unix timestamp when the function is allowed to run next. + pub next_allowed_timestamp: i64, + + /// Reserved. + pub _ebuf: [u8; 512], +} +impl Default for FunctionRoutineAccountData { + fn default() -> Self { + Self { + // Metadata + name: [0u8; 64], + metadata: [0u8; 256], + created_at: 0, + updated_at: 0, + + // Disabled + is_disabled: ResourceLevel::None, + + // Status + status: RoutineStatus::None, + error_status: 0, + enclave_signer: Pubkey::default(), + verifier: Pubkey::default(), + + // Fees + bounty: 0, + + // Accounts + authority: Pubkey::default(), + payer: Pubkey::default(), + function: Pubkey::default(), + attestation_queue: Pubkey::default(), + + escrow_wallet: Pubkey::default(), + escrow_token_wallet: Pubkey::default(), + + // Execution + queue_idx: 0, + schedule: [0u8; 64], + max_container_params_len: 0, + container_params_hash: [0u8; 32], + container_params: vec![], + + // Status / Tracking + last_execution_timestamp: 0, + last_successful_execution_timestamp: 0, + next_allowed_timestamp: 0, + + // Reserved + _ebuf: [0u8; 512], + } + } +} + +impl anchor_lang::AccountSerialize for FunctionRoutineAccountData { + fn try_serialize(&self, writer: &mut W) -> anchor_lang::Result<()> { + if writer + .write_all(&FunctionRoutineAccountData::discriminator()) + .is_err() + { + return Err(anchor_lang::error::ErrorCode::AccountDidNotSerialize.into()); + } + if AnchorSerialize::serialize(self, writer).is_err() { + return Err(anchor_lang::error::ErrorCode::AccountDidNotSerialize.into()); + } + Ok(()) + } +} + +impl anchor_lang::AccountDeserialize for FunctionRoutineAccountData { + fn try_deserialize(buf: &mut &[u8]) -> anchor_lang::Result { + if buf.len() < FunctionRoutineAccountData::discriminator().len() { + return Err(anchor_lang::error::ErrorCode::AccountDiscriminatorNotFound.into()); + } + let given_disc = &buf[..8]; + if FunctionRoutineAccountData::discriminator() != given_disc { + return Err( + anchor_lang::error::Error::from(anchor_lang::error::AnchorError { + error_name: anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch.name(), + error_code_number: anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch + .into(), + error_msg: anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch + .to_string(), + error_origin: Some(anchor_lang::error::ErrorOrigin::Source( + anchor_lang::error::Source { + filename: "programs/attestation_program/src/lib.rs", + line: 1u32, + }, + )), + compared_values: None, + }) + .with_account_name("FunctionRoutineAccountData"), + ); + } + Self::try_deserialize_unchecked(buf) + } + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + let mut data: &[u8] = &buf[8..]; + AnchorDeserialize::deserialize(&mut data) + .map_err(|_| anchor_lang::error::ErrorCode::AccountDidNotDeserialize.into()) + } +} + +impl Discriminator for FunctionRoutineAccountData { + const DISCRIMINATOR: [u8; 8] = [93, 99, 13, 119, 129, 127, 168, 18]; +} + +impl Owner for FunctionRoutineAccountData { + fn owner() -> Pubkey { + SWITCHBOARD_ATTESTATION_PROGRAM_ID + } +} + +impl FunctionRoutineAccountData { + /// Returns the amount of memory space required for a FunctionRoutine account. + /// + /// # Arguments + /// + /// * `len` - An optional `u32` value representing the length of the container parameters vector. + /// + /// # Returns + /// + /// * `usize` - The total amount of memory space required for a FunctionRoutine account. + pub fn space(len: Option) -> usize { + // size of struct if vec is empty + let base: usize = get_instance_packed_len(&FunctionRoutineAccountData::default()).unwrap(); + msg!("FunctionRoutine base usize: {:?}", base); + // let base: usize = 1216; + + // the number of bytes needed for the container params + let vec_elements: usize = len.unwrap_or(DEFAULT_MAX_CONTAINER_PARAMS_LEN) as usize; + + // total bytes + 8 + base + vec_elements + } + + /// Asserts that the length of the account data matches the expected length. + /// + /// # Arguments + /// + /// * `account_info` - The account info to check the data length of. + /// * `len` - The expected length of the account data. + /// + /// # Errors + /// + /// Returns an error if the length of the account data does not match the expected length. + pub fn assert_data_len(account_info: &AccountInfo<'_>, len: Option) -> bool { + let data_len = account_info.data_len(); + // msg!("data_len: {:?}", data_len); + let expected_data_len = Self::space(len); + // msg!("expected_data_len: {:?}", expected_data_len); + + data_len == expected_data_len + + // if data_len != expected_data_len { + // return Err(error!(SwitchboardError::IllegalExecuteAttempt)); + // } + + // Ok(()) + } + + /// Checks if the schedule is empty by reading the first byte. + /// + /// # Returns + /// + /// A boolean indicating whether the schedule is empty or not. + pub fn is_empty_schedule(&self) -> bool { + self.schedule + .first() + .map(|&byte| byte == 0) + .unwrap_or(false) + } + + /// Returns a bool representing whether the routine is disabled for use. + pub fn is_disabled(&self) -> bool { + self.is_disabled.into() + } + + /// Validates the given `signer` account against the `function_account_info` and the enclave_signer + /// stored in this `FunctionRoutineAccountData`. + /// + /// # Arguments + /// + /// * `function_account_info` - The `AccountInfo` of the function account. + /// * `signer` - The `AccountInfo` of the account to validate. + /// + /// # Errors + /// + /// Returns an error if the function account data cannot be loaded or if the `signer` account does not match + /// the expected `enclave_signer`. + /// + /// # Returns + /// + /// Returns `Ok(true)` if the validation succeeds, `Ok(false)` otherwise. + /// + /// # Examples + /// + /// ```ignore + /// use switchboard_solana::FunctionRoutineAccountData; + /// + /// #[derive(Accounts)] + /// pub struct Settle<'info> { + /// // YOUR PROGRAM ACCOUNTS + /// #[account( + /// mut, + /// has_one = switchboard_routine, + /// )] + /// pub user: AccountLoader<'info, UserState>, + /// + /// // SWITCHBOARD ACCOUNTS + /// pub switchboard_function: AccountLoader<'info, FunctionAccountData>, + /// #[account( + /// constraint = switchboard_routine.validate_signer( + /// &switchboard_function.to_account_info(), + /// &enclave_signer.to_account_info() + /// )? + /// )] + /// pub switchboard_routine: Box>, + /// pub enclave_signer: Signer<'info>, + /// } + /// ``` + pub fn validate_signer<'a>( + &self, + function_account_info: &'a AccountInfo<'a>, + signer: &AccountInfo<'a>, + ) -> anchor_lang::Result { + let function_loader = + AccountLoader::<'a, FunctionAccountData>::try_from(function_account_info)?; + + if self.function != function_loader.key() { + msg!( + "FunctionMismatch: expected {}, received {}", + self.function, + function_loader.key() + ); + return Ok(false); + } + + let func = function_loader.load()?; // check owner/discriminator + + if self.attestation_queue != func.attestation_queue { + msg!( + "QueueMismatch: expected {}, received {}", + self.attestation_queue, + func.attestation_queue + ); + return Ok(false); + } + + // validate the enclaves delegated signer matches + if self.enclave_signer != signer.key() { + msg!( + "SignerMismatch: expected {}, received {}", + self.enclave_signer, + signer.key() + ); + return Ok(false); + } + + Ok(true) + } + + pub fn get_name(&self) -> String { + std::str::from_utf8(&self.name) + .unwrap_or("") + .trim() + .to_string() + } + + pub fn get_metadata(&self) -> String { + std::str::from_utf8(&self.metadata) + .unwrap_or("") + .trim() + .to_string() + } +} diff --git a/rust/switchboard-solana/src/attestation_program/accounts/switchboard_wallet.rs b/rust/switchboard-solana/src/attestation_program/accounts/switchboard_wallet.rs index f853ecafb..90996b1b9 100644 --- a/rust/switchboard-solana/src/attestation_program/accounts/switchboard_wallet.rs +++ b/rust/switchboard-solana/src/attestation_program/accounts/switchboard_wallet.rs @@ -1,6 +1,4 @@ -use crate::cfg_client; use crate::prelude::*; -use solana_program::borsh::get_instance_packed_len; #[derive(AnchorDeserialize, AnchorSerialize, Clone)] pub struct SwitchboardWallet { @@ -101,8 +99,8 @@ impl Owner for SwitchboardWallet { impl SwitchboardWallet { pub fn space(len: Option) -> usize { let base: usize = 8 // discriminator - + get_instance_packed_len(&SwitchboardWallet::default()).unwrap(); - let vec_elements: usize = len.unwrap_or(crate::DEFAULT_USERS_CONTAINER_PARAMS_LEN) as usize; + + solana_program::borsh::get_instance_packed_len(&SwitchboardWallet::default()).unwrap(); + let vec_elements: usize = len.unwrap_or(crate::DEFAULT_MAX_CONTAINER_PARAMS_LEN) as usize; base + vec_elements } @@ -131,7 +129,7 @@ impl SwitchboardWallet { )?)) } - pub fn add_resource(&mut self, resource: Pubkey) -> Result<()> { + pub fn add_resource(&mut self, resource: Pubkey) -> anchor_lang::Result<()> { self.resource_count += 1; self.resources.push(resource); @@ -142,7 +140,11 @@ impl SwitchboardWallet { Ok(()) } - pub fn remove_resource(&mut self, resource: Pubkey, idx: Option) -> Result<()> { + pub fn remove_resource( + &mut self, + resource: Pubkey, + idx: Option, + ) -> anchor_lang::Result<()> { self.resource_count -= 1; if let Some(index) = idx { @@ -174,10 +176,8 @@ impl SwitchboardWallet { authority.as_ref(), &SwitchboardWallet::parse_name(&name), ], - &crate::id(), + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, ); pda_key } - - cfg_client! {} } diff --git a/rust/switchboard-solana/src/attestation_program/accounts/verifier.rs b/rust/switchboard-solana/src/attestation_program/accounts/verifier.rs index 59c7d0087..129d2ba31 100644 --- a/rust/switchboard-solana/src/attestation_program/accounts/verifier.rs +++ b/rust/switchboard-solana/src/attestation_program/accounts/verifier.rs @@ -192,7 +192,7 @@ impl VerifierAccountData { self.enclave.enclave_signer } - pub fn assert_signer(&self, signer: &AccountInfo) -> Result<()> { + pub fn assert_signer(&self, signer: &AccountInfo) -> anchor_lang::Result<()> { if self.enclave.enclave_signer != signer.key() { return Err(error!(SwitchboardError::InvalidEnclaveSigner)); } @@ -210,7 +210,7 @@ impl VerifierAccountData { } } - pub fn verify(&self, clock: &Clock) -> Result<()> { + pub fn verify(&self, clock: &Clock) -> anchor_lang::Result<()> { if !self.is_verified(clock) { return Err(error!(SwitchboardError::InvalidQuote)); } @@ -219,11 +219,25 @@ impl VerifierAccountData { } cfg_client! { - pub async fn fetch( + pub fn fetch( client: &solana_client::rpc_client::RpcClient, pubkey: Pubkey, - ) -> std::result::Result { - crate::client::load_account(client, pubkey).await + ) -> std::result::Result { + crate::client::fetch_zerocopy_account(client, pubkey) + } + + pub async fn fetch_async( + client: &solana_client::nonblocking::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_async(client, pubkey).await + } + + pub fn fetch_sync( + client: &T, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_sync(client, pubkey) } } } diff --git a/rust/switchboard-solana/src/attestation_program/client/bootstrapped_queue.rs b/rust/switchboard-solana/src/attestation_program/client/bootstrapped_queue.rs new file mode 100644 index 000000000..7d0afa0c7 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/client/bootstrapped_queue.rs @@ -0,0 +1,569 @@ +#![allow(clippy::too_many_arguments)] +use crate::*; + +use anchor_client::solana_sdk::client::SyncClient; +use kv_log_macro::{info}; +use solana_client::nonblocking::rpc_client::RpcClient as NonblockingRpcClient; +use solana_client::rpc_client::RpcClient; +use solana_program::hash::Hash; +use solana_sdk::message::Message; +use solana_sdk::signature::Signature; +use solana_sdk::signer::keypair::Keypair; +use solana_sdk::signer::Signer; +use solana_sdk::transaction::Transaction; +use std::result::Result; +use std::sync::Arc; +use switchboard_common::SbError; + +/// Parameters used to initialize the bootstrapped attestation queue. +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)] +pub struct BootstrapAttestationQueueParams { + pub reward: Option, + pub allow_authority_override_after: Option, + pub max_quote_verification_age: Option, + pub require_authority_heartbeat_permission: Option, + pub require_usage_permissions: Option, + pub node_timeout: Option, + pub verifier_enclave: Option>, + pub registry_key: Option>, +} +impl Default for BootstrapAttestationQueueParams { + fn default() -> Self { + Self { + reward: Some(0), + allow_authority_override_after: Some(180), + max_quote_verification_age: Some(604800), + require_authority_heartbeat_permission: Some(false), + require_usage_permissions: Some(false), + node_timeout: Some(900), + verifier_enclave: None, + registry_key: Some(vec![]), + } + } +} + +/// Signers used to initialize the bootstrapped attestation queue. +#[derive(Default)] +pub struct BootstrapAttestationQueueSigners { + pub queue_keypair: Option>, + pub authority_keypair: Option>, + + pub verifier_keypair: Option>, + pub verifier_enclave_signer: Option>, +} + +/// Represents a bootstrapped attestation queue with a verifier. +// TODO: store the client so we can automatically relay transactions on-chain +pub struct BootstrappedAttestationQueue { + /// The pubkey of the [`AttestationQueueAccount`] + pub attestation_queue: Pubkey, + /// The pubkey designated as the authority of the [`AttestationQueueAccount`] + pub queue_authority: Pubkey, + + /// The pubkey of the [`VerifierAccountData`] + pub verifier: Pubkey, + /// The pubkey of the [`AttestationPermissionAccount`] + pub verifier_permission: Pubkey, + /// The keypair of the verifier's enclave generated signer. + pub verifier_signer: Arc, + // /// The token account that will receive rewards for verifying requests. + // pub reward_receiver: Pubkey, +} + +/// The default verifier enclave measurement. This is not a valid measurement and should be used for testing only. +pub const DEFAULT_VERIFIER_MR_ENCLAVE: [u8; 32] = [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, +]; + +// TODO: store client and reward_receiver so we can easily send verify transactions +impl BootstrappedAttestationQueue { + pub async fn get_or_create_from_seed( + rpc: &solana_client::nonblocking::rpc_client::RpcClient, + payer: std::sync::Arc, + seed: Option<&str>, + params: Option, + ) -> Result { + let params = params.unwrap_or_default(); + let queue_keypair = crate::keypair_from_base_seed( + format!("attestation-queue-{}", seed.unwrap_or("default")).as_str(), + payer.secret().to_bytes().to_vec(), + Some(params.try_to_vec().unwrap()), + ) + .unwrap(); + let queue_pubkey: Pubkey = queue_keypair.pubkey(); + + let verifier_keypair = crate::keypair_from_base_seed( + format!("verifier-{}-{}", 1, seed.unwrap_or("default")).as_str(), + payer.secret().to_bytes().to_vec(), + None, + ) + .unwrap(); + + let enclave_signer_keypair = crate::keypair_from_base_seed( + format!( + "verifier-{}-enclave-signer-{}", + 1, + seed.unwrap_or("default") + ) + .as_str(), + payer.secret().to_bytes().to_vec(), + None, + ) + .unwrap(); + + let result = if let Err(err) = + AttestationQueueAccountData::fetch_async(rpc, queue_pubkey).await + { + if let SbError::AccountNotFound = &err { + info!( + "[BootstrappedQueue] creating new bootstrapped attestation queue {} ...", + queue_pubkey + ); + + let (queue, signature) = Self::create_async( + rpc, + &payer, + Some(params), + Some(BootstrapAttestationQueueSigners { + queue_keypair: Some(queue_keypair.clone()), + authority_keypair: None, + verifier_keypair: Some(verifier_keypair.clone()), + verifier_enclave_signer: Some(enclave_signer_keypair.clone()), + }), + ) + .await + .map_err(|e| { + println!("Failed to build bootstrapped queue - {:?}", e); + e + }) + .unwrap(); + + info!( + "[BootstrappedQueue] bootstrapped attestation queue {} initialized. Tx Signature: {}", + queue_pubkey, signature + ); + + Ok(queue) + } else { + return Err(err.clone()); + } + } else { + Err(SbError::Generic) + }; + + if let Ok(queue) = result { + return Ok(queue); + } + + let (attestation_queue_result, verifier_data_result) = tokio::join!( + AttestationQueueAccountData::fetch_async(rpc, queue_pubkey), + VerifierAccountData::fetch_async(rpc, verifier_keypair.pubkey()) + ); + + let attestation_queue = attestation_queue_result.unwrap(); + let _verifier_data = verifier_data_result.unwrap(); + + // TODO: verify verifier enclave signer still matches + + info!( + "[BootstrappedQueue] bootstrapped attestation queue loaded {}", + queue_pubkey + ); + + Ok(Self { + attestation_queue: queue_pubkey, + queue_authority: attestation_queue.authority, + verifier: verifier_keypair.pubkey(), + verifier_permission: AttestationPermissionAccountData::get_pda( + &attestation_queue.authority, + &queue_pubkey, + &verifier_keypair.pubkey(), + ), + verifier_signer: enclave_signer_keypair.clone(), + }) + } + + pub fn create_ixs( + payer: Pubkey, + attestation_queue: Pubkey, + verifier: Pubkey, + verifier_signer: Pubkey, + params: Option, + ) -> Result, SbError> { + let params = params.unwrap_or_default(); + + let queue_authority = payer; + // if let Some(authority_pubkey) = authority.as_ref() { + // queue_authority = *authority_pubkey; + // } + + // attestation_queue_init + let attestation_queue_init_ixn = + AttestationQueueInit::build_ix(&AttestationQueueInitArgs { + attestation_queue, + queue_authority: Some(queue_authority), + payer, + allow_authority_override_after: params + .allow_authority_override_after + .unwrap_or(180), + require_authority_heartbeat_permission: params + .require_authority_heartbeat_permission + .unwrap_or_default(), + require_usage_permissions: params.require_usage_permissions.unwrap_or_default(), + max_quote_verification_age: params.max_quote_verification_age.unwrap_or(604800), + reward: params.reward.unwrap_or_default(), + node_timeout: params.node_timeout.unwrap_or(900), + })?; + + // (??) attestation_queue_add_mr_enclave + let mut verifier_enclave = DEFAULT_VERIFIER_MR_ENCLAVE; + if let Some(verifier_enclave_measurement) = params.verifier_enclave { + if verifier_enclave_measurement.len() != 32 { + return Err(SbError::Message("InvalidVerifierEnclaveMeasurement")); + } + verifier_enclave = verifier_enclave_measurement.try_into().unwrap(); + } + let attestation_queue_add_mr_enclave_ixn = + AttestationQueueAddMrEnclave::build_ix(&AttestationQueueAddMrEnclaveArgs { + attestation_queue, + queue_authority, + mr_enclave: verifier_enclave, + })?; + + // verifier_init + let verifier_init_ixn = VerifierInit::build_ix(&VerifierInitArgs { + verifier, + attestation_queue, + queue_authority, + payer, + })?; + + // attestation_permission_init + let verifier_permission_init_ixn = AttestationPermissionInit::build_ix( + attestation_queue, + queue_authority, + verifier, + payer, + )?; + + // (??) attestation_permission_set + let attestation_permission_set_ixn = AttestationPermissionSet::build_ix( + attestation_queue, + queue_authority, + verifier, + SwitchboardAttestationPermission::PermitNodeheartbeat, + true, + )?; + + // verifier_quote_rotate + let mut registry_key = [0u8; 64]; + if let Some(registry_key_vec) = params.registry_key { + if registry_key_vec.len() > 64 { + return Err(SbError::Message("Registry key must be less than 64 bytes")); + } + registry_key[0..registry_key_vec.len()].copy_from_slice(®istry_key_vec[..]); + } + let verifier_quote_rotate_ixn = VerifierQuoteRotate::build_ix( + &verifier, + &queue_authority, + &verifier_signer, + &attestation_queue, + registry_key, + )?; + + // verifier_heartbeat + let verifier_heartbeat_ixn = VerifierHeartbeat::build_ix(VerifierHeartbeatArgs { + verifier, + enclave_signer: verifier_signer, + attestation_queue, + queue_authority, + gc_node: verifier, + })?; + + let ixs = vec![ + attestation_queue_init_ixn, + attestation_queue_add_mr_enclave_ixn, + verifier_init_ixn, + verifier_permission_init_ixn, + attestation_permission_set_ixn, + verifier_quote_rotate_ixn, + verifier_heartbeat_ixn, + ]; + + Ok(ixs) + } + + pub fn create_tx( + payer: &Keypair, + recent_blockhash: Hash, + params: Option, + signers: Option, + ) -> Result<(Self, Transaction), SbError> { + let signers = signers.unwrap_or_default(); + + // Setup signers and accounts + let mut keypairs: Vec<&Keypair> = vec![payer]; + + // let mut authority_pubkey = payer.pubkey(); + // if let Some(authority_keypair) = signers.authority_keypair.as_ref() { + // keypairs.push(authority_keypair); + // authority_pubkey = authority_keypair.pubkey(); + // } + + let queue_keypair = signers.queue_keypair.unwrap_or(Arc::new(Keypair::new())); + keypairs.push(&queue_keypair); + + let verifier_keypair = signers.verifier_keypair.unwrap_or(Arc::new(Keypair::new())); + keypairs.push(&verifier_keypair); + + let verifier_signer = signers + .verifier_enclave_signer + .unwrap_or(Arc::new(Keypair::new())); + keypairs.push(&verifier_signer); + + // for kp in &keypairs { + // println!("keypair {}", kp.pubkey()); + // } + + // println!("payer {}", payer.pubkey()); + // println!("queue {}", queue_keypair.pubkey()); + // println!("verifier {}", verifier_keypair.pubkey()); + // println!("enclave {}", verifier_signer.pubkey()); + + // println!( + // "permission: {}", + // AttestationPermissionAccountData::get_pda( + // &payer.pubkey(), + // &queue_keypair.pubkey(), + // &verifier_keypair.pubkey() + // ) + // ); + + let ixs = Self::create_ixs( + payer.pubkey(), + queue_keypair.pubkey(), + verifier_keypair.pubkey(), + verifier_signer.pubkey(), + params, + )?; + + // let reward_receiver = find_associated_token_address(&payer.pubkey(), &NativeMint::ID); + + let tx = Transaction::new( + &keypairs, + Message::new(&ixs, Some(&payer.pubkey())), + recent_blockhash, + ); + + let queue = BootstrappedAttestationQueue { + attestation_queue: queue_keypair.pubkey(), + queue_authority: payer.pubkey(), + verifier: verifier_keypair.pubkey(), + verifier_permission: AttestationPermissionAccountData::get_pda( + &payer.pubkey(), + &queue_keypair.pubkey(), + &verifier_keypair.pubkey(), + ), + verifier_signer, + }; + + Ok((queue, tx)) + } + + /// Create a new bootstrapped attestation queue using an [`RpcClient'] + pub fn create( + client: &RpcClient, + payer: &Keypair, + params: Option, + signers: Option, + ) -> Result<(Self, Signature), SbError> { + let recent_blockhash = client.get_latest_blockhash().unwrap_or_default(); + // .map_err(|e| SbError::CustomError { + // message: "failed to fetch recent blockhash".to_string(), + // source: std::sync::Arc::new(e), + // })?; + + let (queue, tx) = Self::create_tx(payer, recent_blockhash, params, signers)?; + + let sig = client + .send_and_confirm_transaction(&tx) + .map_err(|e| SbError::CustomError { + message: "failed to send transaction".to_string(), + source: std::sync::Arc::new(e), + })?; + + Ok((queue, sig)) + } + + /// Create a new bootstrapped attestation queue using a [`SyncClient`] + pub fn create_sync( + client: &C, + payer: &Keypair, + params: Option, + signers: Option, + ) -> Result<(Self, Signature), SbError> { + let signers = signers.unwrap_or_default(); + + // Setup signers and accounts + let mut keypairs: Vec<&Keypair> = vec![payer]; + + let authority_pubkey = payer.pubkey(); + // if let Some(authority_keypair) = signers.authority_keypair.as_ref() { + // keypairs.push(authority_keypair); + // authority_pubkey = authority_keypair.pubkey(); + // } + + let queue_keypair = signers.queue_keypair.unwrap_or(Arc::new(Keypair::new())); + keypairs.push(&queue_keypair); + + let verifier_keypair = signers.verifier_keypair.unwrap_or(Arc::new(Keypair::new())); + keypairs.push(&verifier_keypair); + + let verifier_signer = signers + .verifier_enclave_signer + .unwrap_or(Arc::new(Keypair::new())); + keypairs.push(&verifier_signer); + + let ixs = Self::create_ixs( + payer.pubkey(), + queue_keypair.pubkey(), + verifier_keypair.pubkey(), + verifier_signer.pubkey(), + params, + )?; + + let message = Message::new(&ixs, Some(&payer.pubkey())); + + let sig = client + .send_and_confirm_message(&keypairs, message) + .map_err(|e| SbError::CustomError { + message: "failed to send transaction".to_string(), + source: std::sync::Arc::new(e), + })?; + + let queue = BootstrappedAttestationQueue { + attestation_queue: queue_keypair.pubkey(), + queue_authority: authority_pubkey, + verifier: verifier_keypair.pubkey(), + verifier_permission: AttestationPermissionAccountData::get_pda( + &authority_pubkey, + &queue_keypair.pubkey(), + &verifier_keypair.pubkey(), + ), + verifier_signer, + }; + + Ok((queue, sig)) + } + + /// Create a new bootstrapped attestation queue using the nonblocking async rpc client + pub async fn create_async( + client: &NonblockingRpcClient, + payer: &Keypair, + params: Option, + signers: Option, + ) -> Result<(Self, Signature), SbError> { + let recent_blockhash = + client + .get_latest_blockhash() + .await.unwrap_or_default(); + // .map_err(|e| SbError::CustomError { + // message: "failed to fetch recent blockhash".to_string(), + // source: std::sync::Arc::new(e), + // })?; + + let (queue, tx) = Self::create_tx(payer, recent_blockhash, params, signers)?; + + let sig = client + .send_and_confirm_transaction(&tx) + .await + .map_err(|e| SbError::CustomError { + message: "failed to send transaction".to_string(), + source: std::sync::Arc::new(e), + })?; + + Ok((queue, sig)) + } + + pub fn build_function_verify_ix( + &self, + function: Pubkey, + enclave_signer: Pubkey, + function_escrow: Pubkey, + params: FunctionVerifyParams, + reward_receiver: Pubkey, + ) -> Result { + let ix = FunctionVerify::build_ix( + &FunctionVerifyAccounts { + function, + function_enclave_signer: enclave_signer, + function_escrow, + verifier: self.verifier, + verifier_enclave_signer: self.verifier_signer.pubkey(), + reward_receiver, + attestation_queue: self.attestation_queue, + queue_authority: self.queue_authority, + }, + ¶ms, + )?; + + Ok(ix) + } + + pub fn build_request_verify_ix( + &self, + function: Pubkey, + request: Pubkey, + enclave_signer: Pubkey, + params: FunctionRequestVerifyParams, + reward_receiver: Pubkey, + function_escrow_token_wallet: Option, + ) -> Result { + let ix = FunctionRequestVerify::build_ix( + &FunctionRequestVerifyAccounts { + request, + function_enclave_signer: enclave_signer, + function, + function_escrow_token_wallet, + verifier: self.verifier, + verifier_enclave_signer: self.verifier_signer.pubkey(), + reward_receiver, + attestation_queue: self.attestation_queue, + queue_authority: self.queue_authority, + }, + ¶ms, + )?; + + Ok(ix) + } + + pub fn build_routine_verify_ix( + &self, + function: Pubkey, + routine: Pubkey, + enclave_signer: Pubkey, + routine_escrow_wallet: Pubkey, + params: FunctionRoutineVerifyParams, + reward_receiver: Pubkey, + function_escrow_token_wallet: Option, + ) -> Result { + let ix = FunctionRoutineVerify::build_ix( + &FunctionRoutineVerifyAccounts { + routine, + function_enclave_signer: enclave_signer, + function, + escrow_wallet: routine_escrow_wallet, + function_escrow_token_wallet, + verifier: self.verifier, + verifier_enclave_signer: self.verifier_signer.pubkey(), + reward_receiver, + attestation_queue: self.attestation_queue, + queue_authority: self.queue_authority, + }, + ¶ms, + )?; + + Ok(ix) + } +} diff --git a/rust/switchboard-solana/src/attestation_program/client/function.rs b/rust/switchboard-solana/src/attestation_program/client/function.rs new file mode 100644 index 000000000..c2c2e1a4f --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/client/function.rs @@ -0,0 +1,491 @@ +use crate::*; + +use kv_log_macro::{debug, info}; +use sha2::{Digest, Sha256}; +use solana_client::rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}; +use solana_sdk::commitment_config::{CommitmentConfig, CommitmentLevel}; +use solana_sdk::signer::Signer; + +use std::sync::Arc; + +pub const DEFAULT_FUNCTION_MR_ENCLAVE: [u8; 32] = [ + 23, 255, 152, 240, 7, 140, 229, 105, 131, 187, 62, 160, 17, 200, 177, 156, 238, 213, 242, 156, + 153, 94, 5, 77, 91, 218, 183, 146, 181, 206, 173, 108, +]; + +#[derive(Default, Debug, Clone)] +pub struct FunctionFilters { + pub attestation_queue: Option, + pub authority: Option, + pub metadata: Option>, + pub permissions: Option, + // Note: This will not catch functions for which the verifier fetching + // is the secondary oracle. This is because the verifier is not stored + // on the function account but on the queue account. + pub queue_idx: Option, +} +impl FunctionFilters { + pub fn to_vec(&self) -> Vec { + let mut filters = vec![FunctionAccountData::get_discriminator_filter()]; + + // AttestationQueue & Authority Filters + // Combine these two filters for efficiency + if let Some(attestation_queue) = &self.attestation_queue { + if let Some(authority) = &self.authority { + filters.push(FunctionAccountData::get_queue_and_authority_filter( + attestation_queue, + authority, + )); + } else { + filters.push(FunctionAccountData::get_queue_filter(attestation_queue)); + } + } else if let Some(authority) = &self.authority { + filters.push(FunctionAccountData::get_authority_filter(authority)); + } + + // Metadata Filter + if let Some(metadata) = &self.metadata { + filters.push(FunctionAccountData::get_metadata_filter(metadata.clone())); + } + + // Permissions Filter + if let Some(permissions) = &self.permissions { + filters.push(FunctionAccountData::get_permissions_filter(permissions)); + } + + // Queue Idx Filter + if let Some(queue_idx) = &self.queue_idx { + filters.push(FunctionAccountData::get_queue_idx_filter(queue_idx)); + } + + filters + } +} + +impl FunctionAccountData { + pub async fn get_program_accounts( + rpc: &solana_client::nonblocking::rpc_client::RpcClient, + filters: FunctionFilters, + commitment: Option, + ) -> Result, SbError> { + let mut functions = vec![]; + + let accounts = rpc + .get_program_accounts_with_config( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + RpcProgramAccountsConfig { + filters: Some(filters.to_vec()), + account_config: RpcAccountInfoConfig { + encoding: Some(solana_account_decoder::UiAccountEncoding::Base64Zstd), + commitment: Some(CommitmentConfig { + commitment: commitment.unwrap_or(CommitmentLevel::Processed), + }), + ..Default::default() + }, + ..Default::default() + }, + ) + .await + .map_err(|e| SbError::CustomError { + message: "Failed to get program accounts".to_string(), + source: Arc::new(e), + })?; + + for (pubkey, account) in accounts { + if let Ok(function_data) = FunctionAccountData::try_deserialize(&mut &account.data[..]) + { + functions.push((pubkey, function_data)); + } + } + + Ok(functions) + } + + // meh this is a PDA so we can deterministically derive this + // we could set the name to some sha256 hash of the params + // then do a gPA call to filter by name + pub async fn get_or_create_from_seed( + rpc: &solana_client::nonblocking::rpc_client::RpcClient, + payer: std::sync::Arc, + attestation_queue: Pubkey, + seed: Option<&str>, + params: Option, + ) -> Result { + let mut params = params.unwrap_or_default(); + + let mut seed = format!( + "function-{}-{}", + attestation_queue, + seed.unwrap_or("default") + ) + .as_str() + .as_bytes() + .to_vec(); + seed.extend_from_slice(&payer.secret().to_bytes()); + + // were injecting the mrenclave and metadata into the params so cant use params in keypair schema + + // Sha256 hash of the seeds = the metadata of the function + let mut hash = [0u8; 32]; + hash.copy_from_slice(&Sha256::digest(&seed).as_slice()[..32]); + params.metadata = hash.to_vec(); + + // default to some mrenclave value for testing purposes + if let Some(mrenclave) = ¶ms.mr_enclave { + if mrenclave == &[0u8; 32] { + params.mr_enclave = Some(DEFAULT_FUNCTION_MR_ENCLAVE); + } + } else { + params.mr_enclave = Some(DEFAULT_FUNCTION_MR_ENCLAVE); + } + + let functions = FunctionAccountData::get_program_accounts( + rpc, + FunctionFilters { + attestation_queue: Some(attestation_queue), + authority: Some(payer.pubkey()), + metadata: Some(hash.to_vec()), + ..Default::default() + }, + None, + ) + .await?; + + if functions.is_empty() { + // Create a new function + + let slot = rpc.get_slot().await.unwrap(); + let creator_seed = payer.pubkey().to_bytes().to_vec(); + + let (function_pubkey, _bump) = Pubkey::find_program_address( + &[b"FunctionAccountData", &creator_seed, &slot.to_le_bytes()], + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + ); + + info!( + "[Function] creating new function account {} ...", + function_pubkey + ); + + let (address_lookup_table, _) = Pubkey::find_program_address( + &[&function_pubkey.to_bytes(), &slot.to_le_bytes()], + &solana_address_lookup_table_program::ID, + ); + + let name_seed = SwitchboardWallet::parse_name(b"default"); + + // get or create the default switchboard wallet + let switchboard_wallet = SwitchboardWallet::get_or_create_from_seed( + rpc, + payer.clone(), + attestation_queue, + Some(name_seed.to_vec()), + ) + .await + .unwrap(); + + let function_init_ixn = Self::build_ix( + &FunctionInitAccounts { + function: function_pubkey, + address_lookup_table, + authority: payer.pubkey(), + attestation_queue, + payer: payer.pubkey(), + escrow_wallet: switchboard_wallet, + escrow_wallet_authority: None, + }, + &FunctionInitParams { + recent_slot: slot, + creator_seed: None, + metadata: hash.to_vec(), + ..params + }, + ) + .unwrap(); + + let tx = crate::ix_to_tx( + &[function_init_ixn], + &[&*payer], + rpc.get_latest_blockhash().await.unwrap_or_default(), + ) + .unwrap(); + + let signature = rpc.send_and_confirm_transaction(&tx).await.unwrap(); + + info!( + "[Function] switchboard function {} initialized. Tx Signature: {}", + function_pubkey, signature + ); + + Ok(function_pubkey) + } else if functions.len() == 1 { + let function_pubkey = functions[0].0; + + println!("[Function] Found function {}", function_pubkey); + + Ok(function_pubkey) + } else { + let function_pubkey = functions[0].0; + + println!( + "[Function] Found {} functions - {}", + functions.len(), + function_pubkey + ); + debug!("Warning: Too many functions yielded from the getProgramAccounts filter"); + + Ok(function_pubkey) + } + } + + pub fn get_discriminator_filter() -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes( + 0, + FunctionAccountData::discriminator().to_vec(), + ), + ) + } + + pub fn get_permissions_filter(permissions: &u32) -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes( + 10, + permissions.to_le_bytes().to_vec(), + ), + ) + } + + #[deprecated( + since = "0.28.35", + note = "please use a `FunctionRequestAccountData` for all on-demand executions" + )] + pub fn get_is_triggered_filter() -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes(9, vec![1u8]), + ) + } + + #[deprecated( + since = "0.28.35", + note = "please use a `FunctionRoutineAccountData` for all scheduled executions" + )] + pub fn get_is_scheduled_filter() -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes(8, vec![1u8]), + ) + } + + pub fn get_is_active_filter() -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes( + 14, + vec![FunctionStatus::Active as u8], + ), + ) + } + + pub fn get_queue_filter(queue_pubkey: &Pubkey) -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes(2553, queue_pubkey.to_bytes().into()), + ) + } + + pub fn get_authority_filter( + authority_pubkey: &Pubkey, + ) -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes( + 2521, + authority_pubkey.to_bytes().into(), + ), + ) + } + + pub fn get_queue_and_authority_filter( + queue_pubkey: &Pubkey, + authority_pubkey: &Pubkey, + ) -> solana_client::rpc_filter::RpcFilterType { + let bytes = vec![authority_pubkey.to_bytes(), queue_pubkey.to_bytes()].concat(); + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes(2521, bytes), + ) + } + + pub fn get_queue_idx_filter(queue_idx: &u32) -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes(10, queue_idx.to_le_bytes().to_vec()), + ) + } + + pub fn get_metadata_filter(metadata: Vec) -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes(112, metadata), + ) + } + + #[deprecated( + since = "0.28.35", + note = "please use a `FunctionRoutineAccountData` or `FunctionRequestAccountData` for all function executions." + )] + pub fn get_is_ready_filters( + queue_pubkey: &Pubkey, + ) -> Vec { + vec![ + FunctionAccountData::get_discriminator_filter(), + FunctionAccountData::get_is_triggered_filter(), + FunctionAccountData::get_is_scheduled_filter(), + FunctionAccountData::get_is_active_filter(), + FunctionAccountData::get_queue_filter(queue_pubkey), + ] + } + + pub fn get_schedule(&self) -> Option { + if self.schedule[0] == 0 { + return None; + } + let every_second = cron::Schedule::try_from("* * * * * *").unwrap(); + let schedule = std::str::from_utf8(&self.schedule) + .unwrap_or("* * * * * *") + .trim_end_matches('\0'); + let schedule = cron::Schedule::try_from(schedule); + Some(schedule.unwrap_or(every_second)) + } + + pub fn get_last_execution_datetime(&self) -> chrono::DateTime { + chrono::NaiveDateTime::from_timestamp_opt(self.last_execution_timestamp, 0) + .unwrap() + .and_utc() + } + + pub fn get_next_execution_datetime(&self) -> Option> { + let schedule = self.get_schedule()?; + + // If we havent ever executed, use the current timestamp + let last_execution_timestamp = if self.last_execution_timestamp > 0 { + self.last_execution_timestamp + } else { + unix_timestamp() + }; + let last_execution_datetime = + chrono::NaiveDateTime::from_timestamp_opt(last_execution_timestamp, 0) + .unwrap() + .and_utc(); + + schedule.after(&last_execution_datetime).next() + } + + pub fn should_execute(&self, now: chrono::DateTime) -> bool { + if self.is_triggered > 0 { + return true; + } + let schedule = self.get_schedule(); + if schedule.is_none() { + return false; + } + if self.last_execution_timestamp == 0 { + return true; + } + let dt = self.get_last_execution_datetime(); + let next_trigger_time = schedule.unwrap().after(&dt).next(); + if next_trigger_time.is_none() { + return false; + } + let next_trigger_time = next_trigger_time.unwrap(); + if next_trigger_time > now { + return false; + } + true + } + + #[deprecated( + since = "0.28.35", + note = "please use a `FunctionRoutineAccountData` for all scheduled executions" + )] + pub fn is_scheduled(&self) -> bool { + self.schedule[0] == 0 + } + + pub fn fetch( + client: &solana_client::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account(client, pubkey) + } + + pub async fn fetch_async( + client: &solana_client::nonblocking::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_async(client, pubkey).await + } + + pub fn fetch_sync( + client: &T, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_sync(client, pubkey) + } + + pub fn build_ix( + accounts: &FunctionInitAccounts, + params: &FunctionInitParams, + ) -> Result { + Ok(crate::utils::build_ix( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + accounts, + params, + )) + } +} + +pub struct FunctionInitAccounts { + pub function: Pubkey, + pub address_lookup_table: Pubkey, + pub authority: Pubkey, + pub attestation_queue: Pubkey, + pub payer: Pubkey, + pub escrow_wallet: Pubkey, + pub escrow_wallet_authority: Option, +} +impl ToAccountMetas for FunctionInitAccounts { + fn to_account_metas(&self, _: Option) -> Vec { + let mut account_metas = Vec::new(); + + account_metas.push(AccountMeta::new(self.function, false)); + account_metas.push(AccountMeta::new(self.address_lookup_table, false)); + account_metas.push(AccountMeta::new_readonly(self.authority, false)); + account_metas.push(AccountMeta::new_readonly(self.attestation_queue, false)); + account_metas.push(AccountMeta::new(self.payer, true)); + account_metas.push(AccountMeta::new(self.escrow_wallet, false)); + + if let Some(escrow_wallet_authority) = &self.escrow_wallet_authority { + account_metas.push(AccountMeta::new_readonly(*escrow_wallet_authority, true)); + } else { + account_metas.push(AccountMeta::new_readonly( + SWITCHBOARD_ATTESTATION_PROGRAM_ID, + false, + )); + } + + account_metas.push(AccountMeta::new( + find_associated_token_address(&self.escrow_wallet, &NativeMint::id()), + false, + )); + account_metas.push(AccountMeta::new_readonly(NativeMint::ID, false)); + account_metas.push(AccountMeta::new_readonly(anchor_spl::token::ID, false)); + account_metas.push(AccountMeta::new_readonly( + anchor_spl::associated_token::ID, + false, + )); + account_metas.push(AccountMeta::new_readonly( + anchor_lang::system_program::ID, + false, + )); + account_metas.push(AccountMeta::new_readonly( + solana_address_lookup_table_program::ID, + false, + )); + account_metas + } +} diff --git a/rust/switchboard-solana/src/attestation_program/client/mod.rs b/rust/switchboard-solana/src/attestation_program/client/mod.rs new file mode 100644 index 000000000..5f0382564 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/client/mod.rs @@ -0,0 +1,14 @@ +mod request; +pub use request::*; + +mod bootstrapped_queue; +pub use bootstrapped_queue::*; + +mod function; +pub use function::*; + +mod wallet; +pub use wallet::*; + +mod routine; +pub use routine::*; diff --git a/rust/switchboard-solana/src/attestation_program/client/request.rs b/rust/switchboard-solana/src/attestation_program/client/request.rs new file mode 100644 index 000000000..6d49afdb6 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/client/request.rs @@ -0,0 +1,273 @@ +use crate::*; + +use kv_log_macro::info; +use solana_client::rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}; +use solana_sdk::commitment_config::{CommitmentConfig, CommitmentLevel}; +use solana_sdk::signer::Signer; +use std::sync::Arc; + +#[derive(Default, Debug, Clone)] +pub struct FunctionRequestFilters { + pub attestation_queue: Option, + pub authority: Option, + pub is_triggered: Option, + pub is_active: Option, + // Note: This will not catch functions for which the verifier fetching + // is the secondary oracle. This is because the verifier is not stored + // on the function account but on the queue account. + pub queue_idx: Option, +} + +impl FunctionRequestFilters { + pub fn to_vec(&self) -> Vec { + let mut filters = vec![FunctionRequestAccountData::get_discriminator_filter()]; + + // AttestationQueue Filter + if let Some(attestation_queue) = &self.attestation_queue { + filters.push(FunctionRequestAccountData::get_queue_filter( + attestation_queue, + )); + } + + // Authority Filter + if let Some(authority) = &self.authority { + filters.push(FunctionRequestAccountData::get_authority_filter(authority)); + } + + // Combine filters for efficiency + if self.is_triggered.is_some() && self.is_active.is_some() { + filters.push(FunctionRequestAccountData::get_is_triggered_and_active_filter()); + } else { + // Is Triggered Filter + if let Some(is_triggered) = &self.is_triggered { + if *is_triggered { + filters.push(FunctionRequestAccountData::get_is_triggered_filter()); + } + } + + // Is Active Filter + if let Some(is_active) = &self.is_active { + if *is_active { + filters.push(FunctionRequestAccountData::get_is_active_filter()); + } + } + } + + // Queue Idx Filter + if let Some(queue_idx) = &self.queue_idx { + filters.push(FunctionRequestAccountData::get_queue_idx_filter(queue_idx)); + } + + filters + } +} + +impl FunctionRequestAccountData { + ///////////////////////////////////////////////////////////// + /// Client Methods + ///////////////////////////////////////////////////////////// + /// + + pub async fn get_program_accounts( + rpc: &solana_client::nonblocking::rpc_client::RpcClient, + filters: FunctionRequestFilters, + commitment: Option, + ) -> Result, SbError> { + let mut requests = vec![]; + + let accounts = rpc + .get_program_accounts_with_config( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + RpcProgramAccountsConfig { + filters: Some(filters.to_vec()), + account_config: RpcAccountInfoConfig { + encoding: Some(solana_account_decoder::UiAccountEncoding::Base64Zstd), + commitment: Some(CommitmentConfig { + commitment: commitment.unwrap_or(CommitmentLevel::Processed), + }), + ..Default::default() + }, + ..Default::default() + }, + ) + .await + .map_err(|e| SbError::CustomError { + message: "Failed to get program accounts".to_string(), + source: Arc::new(e), + })?; + + for (pubkey, account) in accounts { + if let Ok(request_data) = + FunctionRequestAccountData::try_deserialize(&mut &account.data[..]) + { + requests.push((pubkey, request_data)); + } + } + + Ok(requests) + } + + pub async fn get_or_create_from_seed( + rpc: &solana_client::nonblocking::rpc_client::RpcClient, + payer: std::sync::Arc, + function: Pubkey, + seed: Option<&str>, + params: Option, + ) -> Result { + let params = params.unwrap_or_default(); + let request_keypair = crate::keypair_from_base_seed( + format!("request-{}-{}", function, seed.unwrap_or("default")).as_str(), + payer.secret().to_bytes().to_vec(), + Some(params.try_to_vec().unwrap()), + ) + .unwrap(); + let request_pubkey = request_keypair.pubkey(); + + if let Err(SbError::AccountNotFound) = + FunctionRequestAccountData::fetch_async(rpc, request_pubkey).await + { + info!( + "[Request] creating new request account {} ...", + request_pubkey + ); + + // Fetch function_data and determine if we need authority signer + let function_data = FunctionAccountData::fetch_async(rpc, function) + .await + .unwrap(); + if function_data.requests_require_authorization != 0 + && payer.pubkey() != function_data.authority + { + return Err(SbError::Message("MissingAuthoritySigner")); + } + + // Build the request account and trigger it + let req_init_ixn = FunctionRequestInitAndTrigger::build_ix( + &FunctionRequestInitAndTriggerAccounts { + request: request_pubkey, + authority: payer.pubkey(), + function, + function_authority: None, + attestation_queue: function_data.attestation_queue, + payer: payer.pubkey(), + }, + ¶ms, + ) + .unwrap(); + + let tx = crate::ix_to_tx( + &[req_init_ixn], + &[&*payer, &request_keypair], + rpc.get_latest_blockhash().await.unwrap_or_default(), + ) + .unwrap(); + + let signature = rpc.send_and_confirm_transaction(&tx).await.unwrap(); + + info!( + "[Request] request {} initialized. Tx Signature: {}", + request_pubkey, signature + ); + }; + + Ok(request_pubkey) + } + + ///////////////////////////////////////////////////////////// + /// Fetch Methods + ///////////////////////////////////////////////////////////// + + pub fn fetch( + client: &solana_client::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_borsh_account(client, pubkey) + } + + pub async fn fetch_async( + client: &solana_client::nonblocking::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_borsh_account_async(client, pubkey).await + } + + pub fn fetch_sync( + client: &T, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_borsh_account_sync(client, pubkey) + } + + // + + pub fn get_discriminator_filter() -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes( + 0, + FunctionRequestAccountData::discriminator().to_vec(), + ), + ) + } + + pub fn get_is_triggered_filter() -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes(8, vec![1u8]), + ) + } + + pub fn get_is_active_filter() -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes( + 9, + vec![RequestStatus::RequestPending as u8], + ), + ) + } + + pub fn get_is_triggered_and_active_filter() -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes( + 8, + vec![1u8, RequestStatus::RequestPending as u8], + ), + ) + } + + pub fn get_queue_filter(queue_pubkey: &Pubkey) -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes(138, queue_pubkey.to_bytes().into()), + ) + } + + pub fn get_queue_idx_filter(queue_idx: &u32) -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes(275, queue_idx.to_le_bytes().to_vec()), + ) + } + + pub fn get_authority_filter( + authority_pubkey: &Pubkey, + ) -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes( + 10, + authority_pubkey.to_bytes().into(), + ), + ) + } + + pub fn get_is_ready_filters( + queue_pubkey: &Pubkey, + ) -> Vec { + vec![ + FunctionRequestAccountData::get_discriminator_filter(), + FunctionRequestAccountData::get_is_triggered_filter(), + FunctionRequestAccountData::get_is_active_filter(), + FunctionRequestAccountData::get_queue_filter(queue_pubkey), + ] + } + + pub fn calc_container_params_hash(&self) -> [u8; 32] { + solana_program::hash::hash(&self.container_params).to_bytes() + } +} diff --git a/rust/switchboard-solana/src/attestation_program/client/routine.rs b/rust/switchboard-solana/src/attestation_program/client/routine.rs new file mode 100644 index 000000000..96ebf5268 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/client/routine.rs @@ -0,0 +1,238 @@ +use crate::*; + +use solana_client::rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}; +use solana_sdk::commitment_config::{CommitmentConfig, CommitmentLevel}; +use solana_sdk::signer::Signer; + +use std::sync::Arc; + +#[derive(Default, Debug, Clone)] +pub struct FunctionRoutineFilters { + pub attestation_queue: Option, + pub authority: Option, + pub metadata: Option>, + pub is_enabled: Option, + // Note: This will not catch functions for which the verifier fetching + // is the secondary oracle. This is because the verifier is not stored + // on the function account but on the queue account. + pub queue_idx: Option, +} + +impl FunctionRoutineFilters { + pub fn to_vec(&self) -> Vec { + let mut filters = vec![FunctionRoutineAccountData::get_discriminator_filter()]; + + // AttestationQueue Filter + if let Some(attestation_queue) = &self.attestation_queue { + filters.push(FunctionRoutineAccountData::get_queue_filter( + attestation_queue, + )); + } + + // Authority Filter + if let Some(authority) = &self.authority { + filters.push(FunctionRoutineAccountData::get_authority_filter(authority)); + } + + // Metadata Filter + if let Some(metadata) = &self.metadata { + filters.push(FunctionRoutineAccountData::get_metadata_filter( + metadata.clone(), + )); + } + + // Is Enabled Filter + if let Some(is_enabled) = &self.is_enabled { + if *is_enabled { + filters.push(FunctionRoutineAccountData::get_is_enabled_filter()); + } + } + + // Queue Idx Filter + if let Some(queue_idx) = &self.queue_idx { + filters.push(FunctionRoutineAccountData::get_queue_idx_filter(queue_idx)); + } + + filters + } +} + +impl FunctionRoutineAccountData { + ///////////////////////////////////////////////////////////// + /// Client Methods + ///////////////////////////////////////////////////////////// + + pub async fn get_program_accounts( + rpc: &solana_client::nonblocking::rpc_client::RpcClient, + filters: FunctionRoutineFilters, + commitment: Option, + ) -> Result, SbError> { + let mut routines = vec![]; + + let accounts = rpc + .get_program_accounts_with_config( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + RpcProgramAccountsConfig { + filters: Some(filters.to_vec()), + account_config: RpcAccountInfoConfig { + encoding: Some(solana_account_decoder::UiAccountEncoding::Base64Zstd), + commitment: Some(CommitmentConfig { + commitment: commitment.unwrap_or(CommitmentLevel::Processed), + }), + ..Default::default() + }, + + ..Default::default() + }, + ) + .await + .map_err(|e| SbError::CustomError { + message: "Failed to get program accounts".to_string(), + source: Arc::new(e), + })?; + + for (pubkey, account) in accounts { + if let Ok(routine_data) = + FunctionRoutineAccountData::try_deserialize(&mut &account.data[..]) + { + routines.push((pubkey, routine_data)); + } + } + + Ok(routines) + } + + ///////////////////////////////////////////////////////////// + /// Fetch Methods + ///////////////////////////////////////////////////////////// + + pub fn fetch( + client: &solana_client::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_borsh_account(client, pubkey) + } + + pub async fn fetch_async( + client: &solana_client::nonblocking::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_borsh_account_async(client, pubkey).await + } + + pub fn fetch_sync( + client: &T, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_borsh_account_sync(client, pubkey) + } + + // + + pub fn get_discriminator_filter() -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes( + 0, + FunctionRoutineAccountData::discriminator().to_vec(), + ), + ) + } + + pub fn get_authority_filter( + authority_pubkey: &Pubkey, + ) -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes( + 419, + authority_pubkey.to_bytes().into(), + ), + ) + } + + pub fn get_queue_filter(queue_pubkey: &Pubkey) -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes(515, queue_pubkey.to_bytes().into()), + ) + } + + pub fn get_queue_idx_filter(queue_idx: &u32) -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes(611, queue_idx.to_le_bytes().to_vec()), + ) + } + + pub fn get_is_enabled_filter() -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes(344, 0u8.to_le_bytes().to_vec()), + ) + } + + pub fn get_metadata_filter(metadata: Vec) -> solana_client::rpc_filter::RpcFilterType { + solana_client::rpc_filter::RpcFilterType::Memcmp( + solana_client::rpc_filter::Memcmp::new_raw_bytes(72, metadata), + ) + } + + pub fn get_schedule(&self) -> Option { + if self.schedule[0] == 0 { + return None; + } + let every_second = cron::Schedule::try_from("* * * * * *").unwrap(); + let schedule = std::str::from_utf8(&self.schedule) + .unwrap_or("* * * * * *") + .trim_end_matches('\0'); + let schedule = cron::Schedule::try_from(schedule); + Some(schedule.unwrap_or(every_second)) + } + + pub fn get_last_execution_datetime(&self) -> chrono::DateTime { + chrono::NaiveDateTime::from_timestamp_opt(self.last_execution_timestamp, 0) + .unwrap() + .and_utc() + } + + pub fn get_next_execution_datetime(&self) -> Option> { + let schedule = self.get_schedule()?; + + // If we havent ever executed, use the current timestamp + let last_execution_timestamp = if self.last_execution_timestamp > 0 { + self.last_execution_timestamp + } else { + unix_timestamp() + }; + let last_execution_datetime = + chrono::NaiveDateTime::from_timestamp_opt(last_execution_timestamp, 0) + .unwrap() + .and_utc(); + + schedule.after(&last_execution_datetime).next() + } + + pub fn should_execute(&self, now: chrono::DateTime) -> bool { + let schedule = self.get_schedule(); + if schedule.is_none() { + return false; + } + if self.last_execution_timestamp == 0 { + return true; + } + let dt = self.get_last_execution_datetime(); + let next_trigger_time = schedule.unwrap().after(&dt).next(); + if next_trigger_time.is_none() { + return false; + } + let next_trigger_time = next_trigger_time.unwrap(); + if next_trigger_time > now { + return false; + } + true + } + + pub fn calc_container_params_hash(container_params: &Vec) -> [u8; 32] { + solana_program::hash::hash(container_params).to_bytes() + } + + pub fn get_container_params_hash(&self) -> [u8; 32] { + solana_program::hash::hash(&self.container_params).to_bytes() + } +} diff --git a/rust/switchboard-solana/src/attestation_program/client/wallet.rs b/rust/switchboard-solana/src/attestation_program/client/wallet.rs new file mode 100644 index 000000000..8ab1aeda0 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/client/wallet.rs @@ -0,0 +1,118 @@ +use crate::*; + +use kv_log_macro::{info}; +use solana_sdk::signer::Signer; + + +impl SwitchboardWallet { + pub fn from_seed(attestation_queue: Pubkey, authority: Pubkey, name: Vec) -> Pubkey { + Self::derive_key(NativeMint::ID, attestation_queue, authority, name) + } + + pub fn fetch( + client: &solana_client::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_borsh_account(client, pubkey) + } + + pub async fn fetch_async( + client: &solana_client::nonblocking::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_borsh_account_async(client, pubkey).await + } + + pub fn fetch_sync( + client: &T, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_borsh_account_sync(client, pubkey) + } + + pub async fn get_or_create_from_seed( + rpc: &solana_client::nonblocking::rpc_client::RpcClient, + payer: std::sync::Arc, + attestation_queue: Pubkey, + seed: Option>, + ) -> Result { + let name_seed = seed.unwrap_or(b"default".to_vec()); + if name_seed.len() != 32 { + return Err(SbError::Message("InvalidSeed")); + } + let wallet_pubkey = Self::from_seed(attestation_queue, payer.pubkey(), name_seed.clone()); + + if let Err(SbError::AccountNotFound) = + SwitchboardWallet::fetch_async(rpc, wallet_pubkey).await + { + info!( + "[Wallet] creating new switchboard wallet account {} ...", + wallet_pubkey + ); + + let wallet_init_ixn = WalletInit::build_ix( + &SwitchboardWalletInitAccounts { + wallet: wallet_pubkey, + attestation_queue, + authority: payer.pubkey(), + payer: payer.pubkey(), + }, + &WalletInitParams { + name: name_seed, + max_len: [0u8; 4], + }, + ) + .unwrap(); + + println!( + "[Wallet] ({}) {:?}", + wallet_init_ixn.data.len(), + wallet_init_ixn.data + ); + + let tx = crate::ix_to_tx( + &[wallet_init_ixn], + &[&*payer], + rpc.get_latest_blockhash().await.unwrap_or_default(), + ) + .unwrap(); + + let signature = rpc.send_and_confirm_transaction(&tx).await.unwrap(); + + info!( + "[Wallet] switchboard wallet {} initialized. Tx Signature: {}", + wallet_pubkey, signature + ); + }; + + // TODO: fetch wallet state and balance and send a fund ixn if below a given threshold + + Ok(wallet_pubkey) + } +} + +pub struct SwitchboardWalletInitAccounts { + pub wallet: Pubkey, + pub payer: Pubkey, + pub attestation_queue: Pubkey, + pub authority: Pubkey, +} +impl ToAccountMetas for SwitchboardWalletInitAccounts { + fn to_account_metas(&self, _: Option) -> Vec { + vec![ + AccountMeta::new(self.wallet, false), + AccountMeta::new_readonly(NativeMint::ID, false), + AccountMeta::new_readonly(self.authority, false), + AccountMeta::new_readonly(self.attestation_queue, false), + AccountMeta::new( + find_associated_token_address(&self.wallet, &NativeMint::id()), + false, + ), + AccountMeta::new(self.payer, true), + AccountMeta::new_readonly(AttestationProgramState::get_pda(), false), // TODO: remove + AccountMeta::new_readonly(anchor_spl::token::ID, false), + AccountMeta::new_readonly(anchor_spl::associated_token::ID, false), + AccountMeta::new_readonly(anchor_lang::system_program::ID, false), + ] + } +} diff --git a/rust/switchboard-solana/src/attestation_program/error.rs b/rust/switchboard-solana/src/attestation_program/error.rs new file mode 100644 index 000000000..265c113a6 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/error.rs @@ -0,0 +1,111 @@ +use crate::*; + +// #[repr(u8)] +// pub enum SwitchboardFunctionError { +// /// The function account has invalid permissions for its queue +// InvalidPermissions = 250, +// /// Failed to find the function result in the emitted container logs +// FunctionResultNotFound = 253, +// /// Failed to execute the function's callback +// FunctionCallbackError = 254, +// /// Function failed to emit a result before the oracles timeout +// FunctionTimeout = 255, +// } + +#[error_code] +#[derive(Eq, PartialEq)] +pub enum SwitchboardError { + GenericError, + #[msg("The provided enclave quote is invalid")] + InvalidQuote, + #[msg("The EnclaveAccount has expired and needs to be reverified")] + QuoteExpired, + InvalidNode, + #[msg("The provided queue is empty and has no verifier oracles heartbeating on-chain.")] + InsufficientQueue, + #[msg("The provided queue is full and cannot support new verifiers")] + QueueFull, + #[msg("The provided enclave_signer does not match the expected enclave_signer on the EnclaveAccount")] + InvalidEnclaveSigner, + InvalidSigner, + #[msg("This account has zero mr_enclaves defined")] + MrEnclavesEmpty, + #[msg("The MrEnclave value already exists in the array")] + MrEnclaveAlreadyExists, + #[msg("The MrEnclave value was not found in the whitelist")] + MrEnclaveDoesntExist, + #[msg("This account has a full mr_enclaves array. Remove some measurements to make room for new ones")] + MrEnclaveAtCapacity, + #[msg("The PermissionAccount is missing the required flags for this action. Check the queues config to see which permissions are required")] + PermissionDenied, + InvalidConstraint, + InvalidTimestamp, + InvalidMrEnclave, + InvalidReportData, + InsufficientLoadAmount, + #[msg("The provided timestamp is not within the expected range. This may be indicative of an unhealthy enclave.")] + IncorrectObservedTime, + InvalidQuoteMode, + InvalidVerifierIdx, + InvalidSelfVerifyRequest, + #[msg("The provided mr_enclave measurement did not match a value in its enclave settings. If you recently modified your function container, you may need to update the measurement in your FunctionAccount config.")] + IncorrectMrEnclave, + InvalidResponder, + #[msg("The provided address_lookup_address did not match the expected address on-chain")] + InvalidAddressLookupAddress, + #[msg("The provided attestation queue address did not match the expected address on-chain")] + InvalidQueue, + IllegalVerifier, + InvalidEscrow, + #[msg("The provided authority account does not match the expected value on-chain")] + InvalidAuthority, + IllegalExecuteAttempt, + #[msg("The requests expiration_slot has expired")] + RequestExpired, + #[msg("The escrow has insufficient funds for this action")] + InsufficientFunds, + #[msg("The FunctionAccount escrow is required if function.requests_fee is greater than zero")] + MissingFunctionEscrow, + #[msg("The provided requestSlot did not match the expected requestSlot on-chain. The request may have already been processed")] + InvalidRequest, + #[msg("The FunctionAccount status is not active (1)")] + FunctionNotReady, + #[msg("The FunctionAccount has set requests_disabled to true and disabled this action")] + UserRequestsDisabled, + #[msg( + "The FunctionAccount authority is required to sign if function.requests_require_authorization is enabled" + )] + MissingFunctionAuthority, + #[msg("The FunctionAccount must have no requests before it can be closed")] + FunctionCloseNotReady, + #[msg("Attempting to initialize an already created FunctionRequestAccount")] + RequestAlreadyInitialized, + AccountCloseNotPermitted, + AccountCloseNotReady, + #[msg("The FunctionRequestAccount is not ready to be verified")] + FunctionRequestNotReady, + #[msg("The container params hash does not match the expected hash on-chain. The parameters may have been modified in-flight; the assigned oracle may need to pickup the account change before re-verifying the function.")] + InvalidParamsHash, + RequestInvalidStatus, + #[msg("Please ensure your parameters length is <= your account max length")] + ContainerParamsTooLong, + #[msg("The routine has been disabled. Please check the routine's is_disabled status for more information.")] + RoutineDisabled, + #[msg("The function authority has disabled routine execution for this function")] + FunctionRoutinesDisabled, + #[msg("The configuration parameter has been locked and cannot be changed")] + ConfigParameterLocked, + RequestBufferFull, + #[msg("The request does not have an active round to verify")] + RequestRoundNotActive, + #[msg("The resources escrow token account has a balance of 0 and the queue reward is greater than 0")] + EmptyEscrow, + #[msg( + "The SwitchboardWallet authority must sign this request in order to use its escrow wallet" + )] + MissingSbWalletAuthoritySigner, + #[msg( + "The verifier is attempting to respond to an already closed request round with the same request_slot" + )] + RequestRoundAlreadyClosed, +} diff --git a/rust/switchboard-solana/src/attestation_program/events.rs b/rust/switchboard-solana/src/attestation_program/events.rs new file mode 100644 index 000000000..9dc683a10 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/events.rs @@ -0,0 +1,198 @@ +use crate::*; + +#[event] +pub struct FunctionFundEvent { + pub function: Pubkey, + pub amount: u64, +} + +#[event] +pub struct FunctionRequestInitEvent { + pub attestation_queue: Pubkey, + pub function: Pubkey, + pub request: Pubkey, +} + +#[event] +#[derive(Default, Debug, Clone)] +pub struct FunctionRequestTriggerEvent { + pub attestation_queue: Pubkey, + pub request: Pubkey, + pub function: Pubkey, + pub container_registry: Vec, + pub container: Vec, + pub bounty: u64, + pub request_slot: u64, + pub expiration_slot: u64, + pub container_params_hash: Vec, +} + +#[event] +pub struct FunctionRequestVerifyEvent { + pub request: Pubkey, + pub function: Pubkey, + pub verifier: Pubkey, + pub container_registry: Vec, + pub container: Vec, + pub params: Vec, +} + +#[event] +pub struct FunctionRequestVerifyErrorEvent { + pub request: Pubkey, + pub function: Pubkey, + pub verifier: Pubkey, + pub container_registry: Vec, + pub container: Vec, + pub params: Vec, + pub error_code: u8, +} + +#[event] +pub struct FunctionRequestCloseEvent { + pub request: Pubkey, + pub slot: u64, +} + +#[event] +pub struct FunctionRoutineInitEvent { + pub attestation_queue: Pubkey, + pub function: Pubkey, + pub routine: Pubkey, + pub schedule: [u8; 64], +} + +#[event] +pub struct FunctionRoutineVerifyEvent { + pub routine: Pubkey, + pub function: Pubkey, + pub verifier: Pubkey, + pub mr_enclave: Vec, + pub container_registry: Vec, + pub container: Vec, + pub params: Vec, +} + +#[event] +pub struct FunctionRoutineVerifyErrorEvent { + pub routine: Pubkey, + pub function: Pubkey, + pub verifier: Pubkey, + pub mr_enclave: Vec, + pub container_registry: Vec, + pub container: Vec, + pub params: Vec, + pub error_code: u8, +} + +// TODO: deprecate +#[event] +pub struct FunctionTriggerEvent { + pub function: Pubkey, +} + +#[event] +pub struct FunctionInitEvent { + pub function: Pubkey, + pub container_registry: Vec, + pub container: Vec, + pub version: Vec, + pub schedule: Vec, + pub mr_enclave: Vec, +} + +#[event] +#[derive(Default, Debug, Clone)] +pub struct FunctionSetConfigEvent { + pub function: Pubkey, + pub container_registry: Vec, + pub container: Vec, + pub version: Vec, + pub schedule: Vec, + pub mr_enclaves: Vec>, +} + +#[event] +pub struct FunctionBootedEvent { + pub function: Pubkey, +} + +// TODO: deprecate +#[event] +pub struct FunctionVerifyEvent { + pub function: Pubkey, +} + +#[event] +pub struct FunctionWithdrawEvent { + pub function: Pubkey, + pub amount: u64, +} + +#[event] +pub struct PermissionInitEvent { + pub permission: Pubkey, +} + +#[event] +pub struct PermissionSetEvent { + pub permission: Pubkey, +} + +#[event] +pub struct QueueAddMrEnclaveEvent { + pub queue: Pubkey, + pub mr_enclave: [u8; 32], +} + +#[event] +pub struct QueueInitEvent { + pub queue: Pubkey, +} + +#[event] +pub struct QueueRemoveMrEnclaveEvent { + pub queue: Pubkey, + pub mr_enclave: [u8; 32], +} + +#[event] +pub struct VerifierHeartbeatEvent { + pub verifier: Pubkey, + pub queue: Pubkey, +} + +#[event] +pub struct VerifierInitEvent { + pub verifier: Pubkey, +} + +#[event] +pub struct VerifierQuoteRotateEvent { + pub verifier: Pubkey, +} + +#[event] +pub struct VerifierQuoteOverrideEvent { + pub verifier: Pubkey, + pub queue: Pubkey, +} + +#[event] +pub struct GarbageCollectionEvent { + pub verifier: Pubkey, + pub queue: Pubkey, +} + +#[event] +pub struct VerifierQuoteVerifyEvent { + pub quote: Pubkey, + pub queue: Pubkey, + pub verifier: Pubkey, +} + +#[event] +pub struct VerifierQuoteVerifyRequestEvent { + pub quote: Pubkey, + pub verifier: Pubkey, +} diff --git a/rust/switchboard-solana/src/attestation_program/instructions/attestation_permission_init.rs b/rust/switchboard-solana/src/attestation_program/instructions/attestation_permission_init.rs new file mode 100644 index 000000000..46812420e --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/instructions/attestation_permission_init.rs @@ -0,0 +1,128 @@ +use crate::cfg_client; +use crate::prelude::*; + +#[derive(Accounts)] +#[instruction(params:AttestationPermissionInitParams)] +pub struct AttestationPermissionInit<'info> { + #[account(mut)] + pub permission: AccountInfo<'info>, + + /// CHECK: + pub authority: AccountInfo<'info>, + + pub attestation_queue: AccountInfo<'info>, + + /// CHECK: + pub node: AccountInfo<'info>, + + #[account(mut, signer)] + pub payer: AccountInfo<'info>, + + pub system_program: AccountInfo<'info>, +} + +#[derive(Clone, AnchorSerialize, AnchorDeserialize)] +pub struct AttestationPermissionInitParams {} + +impl InstructionData for AttestationPermissionInitParams {} + +impl Discriminator for AttestationPermissionInitParams { + const DISCRIMINATOR: [u8; 8] = [219, 80, 131, 73, 164, 190, 142, 215]; +} + +impl Discriminator for AttestationPermissionInit<'_> { + const DISCRIMINATOR: [u8; 8] = [219, 80, 131, 73, 164, 190, 142, 215]; +} + +cfg_client! { + pub struct AttestationPermissionInitAccounts { + pub queue_authority: Pubkey, + pub attestation_queue: Pubkey, + pub node: Pubkey, + pub payer: Pubkey, + } + impl ToAccountMetas for AttestationPermissionInitAccounts { + fn to_account_metas(&self, _: Option) -> Vec { + vec![ + AccountMeta::new(AttestationPermissionAccountData::get_pda(&self.queue_authority, &self.attestation_queue, &self.node), false), + AccountMeta::new_readonly(self.queue_authority, true), + AccountMeta::new_readonly(self.attestation_queue, false), + AccountMeta::new_readonly(self.node, true), + AccountMeta::new(self.payer, true), + AccountMeta::new_readonly(solana_program::system_program::ID, false), + ] + } + } +} + +impl<'info> AttestationPermissionInit<'info> { + pub fn get_instruction(&self, program_id: Pubkey) -> anchor_lang::Result { + let accounts = self.to_account_metas(None); + + let instruction = Instruction::new_with_bytes( + program_id, + &AttestationPermissionInit::discriminator().try_to_vec()?, + accounts, + ); + Ok(instruction) + } + + pub fn invoke(&self, program: AccountInfo<'info>) -> ProgramResult { + let instruction = self.get_instruction(*program.key)?; + let account_infos = self.to_account_infos(); + + invoke(&instruction, &account_infos[..]) + } + + pub fn invoke_signed( + &self, + program: AccountInfo<'info>, + signer_seeds: &[&[&[u8]]], + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key)?; + let account_infos = self.to_account_infos(); + + invoke_signed(&instruction, &account_infos[..], signer_seeds) + } + + fn to_account_infos(&self) -> Vec> { + let mut account_infos = Vec::new(); + account_infos.extend(self.permission.to_account_infos()); + account_infos.extend(self.authority.to_account_infos()); + account_infos.extend(self.attestation_queue.to_account_infos()); + account_infos.extend(self.node.to_account_infos()); + account_infos.extend(self.payer.to_account_infos()); + account_infos.extend(self.system_program.to_account_infos()); + + account_infos + } + + #[allow(unused_variables)] + fn to_account_metas(&self, is_signer: Option) -> Vec { + let mut account_metas = Vec::new(); + account_metas.extend(self.permission.to_account_metas(None)); + account_metas.extend(self.authority.to_account_metas(None)); + account_metas.extend(self.attestation_queue.to_account_metas(None)); + account_metas.extend(self.node.to_account_metas(None)); + account_metas.extend(self.payer.to_account_metas(Some(true))); + account_metas.extend(self.system_program.to_account_metas(None)); + + account_metas + } + + cfg_client! { + pub fn build_ix( + attestation_queue: Pubkey, queue_authority: Pubkey, node: Pubkey, payer: Pubkey, + ) -> Result { + Ok( + crate::utils::build_ix( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + &AttestationPermissionInitAccounts { + queue_authority, attestation_queue, node, payer, + }, + &AttestationPermissionInitParams{}, + ) + ) + } + } +} diff --git a/rust/switchboard-solana/src/attestation_program/instructions/attestation_permission_set.rs b/rust/switchboard-solana/src/attestation_program/instructions/attestation_permission_set.rs new file mode 100644 index 000000000..602f8662c --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/instructions/attestation_permission_set.rs @@ -0,0 +1,127 @@ +use crate::cfg_client; +use crate::prelude::*; + +#[derive(Accounts)] +#[instruction(params:AttestationPermissionSetParams)] +pub struct AttestationPermissionSet<'info> { + #[account(mut)] + pub permission: AccountInfo<'info>, + + /// CHECK: + #[account(signer)] + pub authority: AccountInfo<'info>, + + pub attestation_queue: AccountInfo<'info>, + + /// CHECK: + pub grantee: AccountInfo<'info>, +} + +#[derive(Clone, AnchorSerialize, AnchorDeserialize)] +pub struct AttestationPermissionSetParams { + pub permission: u32, + pub enable: bool, +} + +impl InstructionData for AttestationPermissionSetParams {} + +impl Discriminator for AttestationPermissionSetParams { + const DISCRIMINATOR: [u8; 8] = [56, 253, 255, 201, 100, 153, 10, 76]; +} + +impl Discriminator for AttestationPermissionSet<'_> { + const DISCRIMINATOR: [u8; 8] = [56, 253, 255, 201, 100, 153, 10, 76]; +} + +cfg_client! { + pub struct AttestationPermissionSetAccounts { + pub queue_authority: Pubkey, + pub attestation_queue: Pubkey, + pub grantee: Pubkey, + } + impl ToAccountMetas for AttestationPermissionSetAccounts { + fn to_account_metas(&self, _: Option) -> Vec { + vec![ + AccountMeta::new(AttestationPermissionAccountData::get_pda(&self.queue_authority, &self.attestation_queue, &self.grantee), false), + AccountMeta::new_readonly(self.queue_authority, true), + AccountMeta::new_readonly(self.attestation_queue, false), + AccountMeta::new_readonly(self.grantee, true), + ] + } + } +} + +impl<'info> AttestationPermissionSet<'info> { + pub fn get_instruction(&self, program_id: Pubkey) -> anchor_lang::Result { + let accounts = self.to_account_metas(None); + + let instruction = Instruction::new_with_bytes( + program_id, + &AttestationPermissionSet::discriminator().try_to_vec()?, + accounts, + ); + Ok(instruction) + } + + pub fn invoke(&self, program: AccountInfo<'info>) -> ProgramResult { + let instruction = self.get_instruction(*program.key)?; + let account_infos = self.to_account_infos(); + + invoke(&instruction, &account_infos[..]) + } + + pub fn invoke_signed( + &self, + program: AccountInfo<'info>, + signer_seeds: &[&[&[u8]]], + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key)?; + let account_infos = self.to_account_infos(); + + invoke_signed(&instruction, &account_infos[..], signer_seeds) + } + + fn to_account_infos(&self) -> Vec> { + let mut account_infos = Vec::new(); + account_infos.extend(self.permission.to_account_infos()); + account_infos.extend(self.authority.to_account_infos()); + account_infos.extend(self.attestation_queue.to_account_infos()); + account_infos.extend(self.grantee.to_account_infos()); + + account_infos + } + + #[allow(unused_variables)] + fn to_account_metas(&self, is_signer: Option) -> Vec { + let mut account_metas = Vec::new(); + account_metas.extend(self.permission.to_account_metas(None)); + account_metas.extend(self.authority.to_account_metas(None)); + account_metas.extend(self.attestation_queue.to_account_metas(None)); + account_metas.extend(self.grantee.to_account_metas(None)); + + account_metas + } + + cfg_client! { + pub fn build_ix( + attestation_queue: Pubkey, + queue_authority: Pubkey, + grantee: Pubkey, + permission: SwitchboardAttestationPermission, + enable: bool, + ) -> Result { + Ok( + crate::utils::build_ix( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + &AttestationPermissionSetAccounts { + queue_authority, attestation_queue, grantee + }, + &AttestationPermissionSetParams { + permission: permission.into(), + enable + }, + ) + ) + } + } +} diff --git a/rust/switchboard-solana/src/attestation_program/instructions/attestation_queue_add_mrenclave.rs b/rust/switchboard-solana/src/attestation_program/instructions/attestation_queue_add_mrenclave.rs new file mode 100644 index 000000000..28de927f5 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/instructions/attestation_queue_add_mrenclave.rs @@ -0,0 +1,122 @@ +use crate::cfg_client; +use crate::prelude::*; + +#[derive(Accounts)] +#[instruction(params:AttestationQueueAddMrEnclaveParams)] +pub struct AttestationQueueAddMrEnclave<'info> { + #[account(mut)] + pub queue: AccountInfo<'info>, + + #[account(signer)] + pub authority: AccountInfo<'info>, +} + +#[derive(Clone, AnchorSerialize, AnchorDeserialize)] +pub struct AttestationQueueAddMrEnclaveParams { + pub mr_enclave: [u8; 32], +} + +impl InstructionData for AttestationQueueAddMrEnclaveParams {} + +impl Discriminator for AttestationQueueAddMrEnclaveParams { + const DISCRIMINATOR: [u8; 8] = [62, 27, 24, 221, 30, 240, 63, 167]; +} + +impl Discriminator for AttestationQueueAddMrEnclave<'_> { + const DISCRIMINATOR: [u8; 8] = [62, 27, 24, 221, 30, 240, 63, 167]; +} + +cfg_client! { + pub struct AttestationQueueAddMrEnclaveArgs { + pub attestation_queue: Pubkey, + pub queue_authority: Pubkey, + pub mr_enclave: [u8; 32], + } + + pub struct AttestationQueueAddMrEnclaveAccounts { + pub attestation_queue: Pubkey, + pub queue_authority: Pubkey, + } + impl ToAccountMetas for AttestationQueueAddMrEnclaveAccounts { + fn to_account_metas(&self, _: Option) -> Vec { + vec![ + + AccountMeta::new(self.attestation_queue, false), + AccountMeta::new_readonly(self.queue_authority, false), + ] + } + } +} + +impl<'info> AttestationQueueAddMrEnclave<'info> { + pub fn get_instruction( + &self, + program_id: Pubkey, + params: &AttestationQueueAddMrEnclaveParams, + ) -> anchor_lang::Result { + let accounts = self.to_account_metas(None); + + let mut data: Vec = AttestationQueueAddMrEnclave::discriminator().try_to_vec()?; + data.append(&mut params.try_to_vec()?); + + let instruction = Instruction::new_with_bytes(program_id, &data, accounts); + Ok(instruction) + } + + pub fn invoke( + &self, + program: AccountInfo<'info>, + params: &AttestationQueueAddMrEnclaveParams, + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key, params)?; + let account_infos = self.to_account_infos(); + + invoke(&instruction, &account_infos[..]) + } + + pub fn invoke_signed( + &self, + program: AccountInfo<'info>, + params: &AttestationQueueAddMrEnclaveParams, + signer_seeds: &[&[&[u8]]], + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key, params)?; + let account_infos = self.to_account_infos(); + + invoke_signed(&instruction, &account_infos[..], signer_seeds) + } + + fn to_account_infos(&self) -> Vec> { + let mut account_infos = Vec::new(); + account_infos.extend(self.queue.to_account_infos()); + account_infos.extend(self.authority.to_account_infos()); + account_infos + } + + #[allow(unused_variables)] + fn to_account_metas(&self, is_signer: Option) -> Vec { + let mut account_metas = Vec::new(); + account_metas.extend(self.queue.to_account_metas(None)); + account_metas.extend(self.authority.to_account_metas(None)); + account_metas + } + + cfg_client! { + pub fn build_ix( + args: &AttestationQueueAddMrEnclaveArgs, + ) -> Result { + Ok( + crate::utils::build_ix( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + &AttestationQueueAddMrEnclaveAccounts { + attestation_queue: args.attestation_queue, + queue_authority: args.queue_authority, + }, + &AttestationQueueAddMrEnclaveParams { + mr_enclave: args.mr_enclave + }, + ) + ) + } + } +} diff --git a/rust/switchboard-solana/src/attestation_program/instructions/attestation_queue_init.rs b/rust/switchboard-solana/src/attestation_program/instructions/attestation_queue_init.rs new file mode 100644 index 000000000..0290d7fa6 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/instructions/attestation_queue_init.rs @@ -0,0 +1,150 @@ +use crate::cfg_client; +use crate::prelude::*; + +#[derive(Accounts)] +#[instruction(params:AttestationQueueInitParams)] +pub struct AttestationQueueInit<'info> { + #[account(mut, signer)] + pub queue: AccountInfo<'info>, + + /// CHECK: + pub authority: AccountInfo<'info>, + + #[account(mut, signer)] + pub payer: AccountInfo<'info>, + + pub system_program: AccountInfo<'info>, +} + +#[derive(Clone, AnchorSerialize, AnchorDeserialize)] +pub struct AttestationQueueInitParams { + pub allow_authority_override_after: u32, + pub require_authority_heartbeat_permission: bool, + pub require_usage_permissions: bool, + pub max_quote_verification_age: u32, + pub reward: u32, + pub node_timeout: u32, +} + +impl InstructionData for AttestationQueueInitParams {} + +impl Discriminator for AttestationQueueInitParams { + const DISCRIMINATOR: [u8; 8] = [82, 211, 133, 63, 177, 112, 210, 216]; +} + +impl Discriminator for AttestationQueueInit<'_> { + const DISCRIMINATOR: [u8; 8] = [82, 211, 133, 63, 177, 112, 210, 216]; +} + +cfg_client! { + pub struct AttestationQueueInitArgs { + pub attestation_queue: Pubkey, + pub queue_authority: Option, + pub payer: Pubkey, + pub allow_authority_override_after: u32, + pub require_authority_heartbeat_permission: bool, + pub require_usage_permissions: bool, + pub max_quote_verification_age: u32, + pub reward: u32, + pub node_timeout: u32, + } + + pub struct AttestationQueueInitAccounts { + pub attestation_queue: Pubkey, + pub queue_authority: Option, + pub payer: Pubkey, + } + impl ToAccountMetas for AttestationQueueInitAccounts { + fn to_account_metas(&self, _: Option) -> Vec { + vec![ + AccountMeta::new(self.attestation_queue, true), + AccountMeta::new_readonly(self.queue_authority.unwrap_or(self.payer), false), + AccountMeta::new(self.payer, true), + AccountMeta::new_readonly(solana_program::system_program::ID, false), + ] + } + } +} + +impl<'info> AttestationQueueInit<'info> { + pub fn get_instruction( + &self, + program_id: Pubkey, + params: &AttestationQueueInitParams, + ) -> anchor_lang::Result { + let accounts = self.to_account_metas(None); + + let mut data: Vec = AttestationQueueInit::discriminator().try_to_vec()?; + data.append(&mut params.try_to_vec()?); + + let instruction = Instruction::new_with_bytes(program_id, &data, accounts); + Ok(instruction) + } + + pub fn invoke( + &self, + program: AccountInfo<'info>, + params: &AttestationQueueInitParams, + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key, params)?; + let account_infos = self.to_account_infos(); + + invoke(&instruction, &account_infos[..]) + } + + pub fn invoke_signed( + &self, + program: AccountInfo<'info>, + params: &AttestationQueueInitParams, + signer_seeds: &[&[&[u8]]], + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key, params)?; + let account_infos = self.to_account_infos(); + + invoke_signed(&instruction, &account_infos[..], signer_seeds) + } + + fn to_account_infos(&self) -> Vec> { + let mut account_infos = Vec::new(); + account_infos.extend(self.queue.to_account_infos()); + account_infos.extend(self.authority.to_account_infos()); + account_infos.extend(self.payer.to_account_infos()); + account_infos.extend(self.system_program.to_account_infos()); + account_infos + } + + #[allow(unused_variables)] + fn to_account_metas(&self, is_signer: Option) -> Vec { + let mut account_metas = Vec::new(); + account_metas.extend(self.queue.to_account_metas(None)); + account_metas.extend(self.authority.to_account_metas(None)); + account_metas.extend(self.payer.to_account_metas(None)); + account_metas.extend(self.system_program.to_account_metas(None)); + account_metas + } + + cfg_client! { + pub fn build_ix( + args: &AttestationQueueInitArgs, + ) -> Result { + Ok( + crate::utils::build_ix( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + &AttestationQueueInitAccounts { + attestation_queue: args.attestation_queue, + queue_authority: args.queue_authority, + payer: args.payer, + }, + &AttestationQueueInitParams { + allow_authority_override_after: args.allow_authority_override_after, + require_authority_heartbeat_permission: args.require_authority_heartbeat_permission, + require_usage_permissions: args.require_usage_permissions, + max_quote_verification_age: args.max_quote_verification_age, + reward: args.reward, + node_timeout: args.node_timeout, + }, + ) + ) + } + } +} diff --git a/rust/switchboard-solana/src/attestation_program/instructions/function_close.rs b/rust/switchboard-solana/src/attestation_program/instructions/function_close.rs index 0c1e920ef..1321ce353 100644 --- a/rust/switchboard-solana/src/attestation_program/instructions/function_close.rs +++ b/rust/switchboard-solana/src/attestation_program/instructions/function_close.rs @@ -3,8 +3,23 @@ use crate::prelude::*; #[derive(Accounts)] #[instruction(params:FunctionCloseParams)] pub struct FunctionClose<'info> { + /// #[account( + /// mut, + /// close = sol_dest, + /// seeds = [ + /// FUNCTION_SEED, + /// function.load()?.creator_seed.as_ref(), + /// &function.load()?.created_at_slot.to_le_bytes() + /// ], + /// bump = function.load()?.bump, + /// has_one = authority @ SwitchboardError::InvalidAuthority, + /// has_one = address_lookup_table, + /// has_one = escrow_wallet, + /// )] + /// pub function: AccountLoader<'info, FunctionAccountData>, #[account(mut)] pub function: AccountInfo<'info>, + #[account(signer)] pub authority: AccountInfo<'info>, @@ -15,17 +30,26 @@ pub struct FunctionClose<'info> { )] pub address_lookup_table: AccountInfo<'info>, + /// pub escrow_wallet: Box>, #[account(mut)] pub escrow_wallet: AccountInfo<'info>, // SwitchboardWallet /// CHECK: pub sol_dest: AccountInfo<'info>, + /// #[account( + /// mut, + /// constraint = escrow_dest.is_native() + /// )] + /// pub escrow_dest: Box>, #[account(mut)] pub escrow_dest: AccountInfo<'info>, - pub state: AccountInfo<'info>, + + /// pub token_program: Program<'info, Token>, #[account(address = anchor_spl::token::ID)] pub token_program: AccountInfo<'info>, + + /// pub system_program: Program<'info, System>, #[account(address = solana_program::system_program::ID)] pub system_program: AccountInfo<'info>, @@ -88,7 +112,6 @@ impl<'info> FunctionClose<'info> { account_infos.extend(self.escrow_wallet.to_account_infos()); account_infos.extend(self.sol_dest.to_account_infos()); account_infos.extend(self.escrow_dest.to_account_infos()); - account_infos.extend(self.state.to_account_infos()); account_infos.extend(self.token_program.to_account_infos()); account_infos.extend(self.system_program.to_account_infos()); account_infos.extend(self.address_lookup_program.to_account_infos()); @@ -104,7 +127,6 @@ impl<'info> FunctionClose<'info> { account_metas.extend(self.escrow_wallet.to_account_metas(None)); account_metas.extend(self.sol_dest.to_account_metas(None)); account_metas.extend(self.escrow_dest.to_account_metas(None)); - account_metas.extend(self.state.to_account_metas(None)); account_metas.extend(self.token_program.to_account_metas(None)); account_metas.extend(self.system_program.to_account_metas(None)); account_metas.extend(self.address_lookup_program.to_account_metas(None)); diff --git a/rust/switchboard-solana/src/attestation_program/instructions/function_init.rs b/rust/switchboard-solana/src/attestation_program/instructions/function_init.rs index a3fb7f218..e76d6495b 100644 --- a/rust/switchboard-solana/src/attestation_program/instructions/function_init.rs +++ b/rust/switchboard-solana/src/attestation_program/instructions/function_init.rs @@ -25,14 +25,14 @@ pub struct FunctionInit<'info> { /// CHECK: handle this manually because the PDA seed can vary #[account(mut)] - pub wallet: AccountInfo<'info>, + pub escrow_wallet: AccountInfo<'info>, #[account(signer)] - pub wallet_authority: Option>, + pub escrow_wallet_authority: Option>, /// CHECK: handle this manually because the PDA seed can vary #[account(mut)] - pub token_wallet: AccountInfo<'info>, + pub escrow_token_wallet: AccountInfo<'info>, #[account(address = anchor_spl::token::spl_token::native_mint::ID)] pub mint: AccountInfo<'info>, @@ -51,20 +51,33 @@ pub struct FunctionInit<'info> { pub address_lookup_program: AccountInfo<'info>, } -#[derive(Clone, AnchorSerialize, AnchorDeserialize)] +#[derive(Clone, Default, AnchorSerialize, AnchorDeserialize)] pub struct FunctionInitParams { + // PDA fields + pub recent_slot: u64, + pub creator_seed: Option<[u8; 32]>, + + // Metadata pub name: Vec, pub metadata: Vec, + + // Container Config pub container: Vec, pub container_registry: Vec, pub version: Vec, - pub schedule: Vec, - pub mr_enclave: [u8; 32], - pub recent_slot: u64, + pub mr_enclave: Option<[u8; 32]>, + + // pub schedule: Vec, + + // Request Config pub requests_disabled: bool, pub requests_require_authorization: bool, - pub requests_fee: u64, - pub creator_seed: Option<[u8; 32]>, + pub requests_dev_fee: u64, + + // Routines Config + pub routines_disabled: bool, + pub routines_require_authorization: bool, + pub routines_dev_fee: u64, } impl InstructionData for FunctionInitParams {} @@ -122,9 +135,9 @@ impl<'info> FunctionInit<'info> { account_infos.extend(self.authority.to_account_infos()); account_infos.extend(self.attestation_queue.to_account_infos()); account_infos.extend(self.payer.to_account_infos()); - account_infos.extend(self.wallet.to_account_infos()); - account_infos.extend(self.wallet_authority.to_account_infos()); - account_infos.extend(self.token_wallet.to_account_infos()); + account_infos.extend(self.escrow_wallet.to_account_infos()); + account_infos.extend(self.escrow_wallet_authority.to_account_infos()); + account_infos.extend(self.escrow_token_wallet.to_account_infos()); account_infos.extend(self.mint.to_account_infos()); account_infos.extend(self.token_program.to_account_infos()); account_infos.extend(self.associated_token_program.to_account_infos()); @@ -140,14 +153,17 @@ impl<'info> FunctionInit<'info> { account_metas.extend(self.address_lookup_table.to_account_metas(None)); account_metas.extend(self.authority.to_account_metas(None)); account_metas.extend(self.attestation_queue.to_account_metas(None)); - account_metas.extend(self.payer.to_account_metas(None)); - account_metas.extend(self.wallet.to_account_metas(None)); - if let Some(wallet_authority) = &self.wallet_authority { - account_metas.extend(wallet_authority.to_account_metas(None)); + account_metas.extend(self.payer.to_account_metas(Some(true))); + account_metas.extend(self.escrow_wallet.to_account_metas(None)); + if let Some(escrow_wallet_authority) = &self.escrow_wallet_authority { + account_metas.extend(escrow_wallet_authority.to_account_metas(Some(true))); } else { - account_metas.push(AccountMeta::new_readonly(crate::ID, false)); + account_metas.push(AccountMeta::new_readonly( + SWITCHBOARD_ATTESTATION_PROGRAM_ID, + false, + )); } - account_metas.extend(self.token_wallet.to_account_metas(None)); + account_metas.extend(self.escrow_token_wallet.to_account_metas(None)); account_metas.extend(self.mint.to_account_metas(None)); account_metas.extend(self.token_program.to_account_metas(None)); account_metas.extend(self.associated_token_program.to_account_metas(None)); diff --git a/rust/switchboard-solana/src/attestation_program/instructions/function_verify.rs b/rust/switchboard-solana/src/attestation_program/instructions/function_verify.rs index 66473632f..965814ef2 100644 --- a/rust/switchboard-solana/src/attestation_program/instructions/function_verify.rs +++ b/rust/switchboard-solana/src/attestation_program/instructions/function_verify.rs @@ -1,22 +1,73 @@ +use crate::cfg_client; use crate::prelude::*; #[derive(Accounts)] #[instruction(params: FunctionVerifyParams)] // rpc parameters hint pub struct FunctionVerify<'info> { + /// #[account( + /// mut, + /// seeds = [ + /// FUNCTION_SEED, + /// function.load()?.creator_seed.as_ref(), + /// &function.load()?.created_at_slot.to_le_bytes() + /// ], + /// bump = function.load()?.bump, + /// has_one = attestation_queue @ SwitchboardError::InvalidQueue, + /// has_one = escrow_token_wallet @ SwitchboardError::InvalidEscrow, + /// has_one = escrow_wallet, + /// )] + /// pub function: AccountLoader<'info, FunctionAccountData>, #[account(mut)] pub function: AccountInfo<'info>, // FunctionAccountData - #[account(signer)] - pub function_enclave_signer: AccountInfo<'info>, // SystemProgram keypair + + // #[account(signer)] + pub function_enclave_signer: Signer<'info>, // SystemProgram keypair + + /// #[account( + /// has_one = attestation_queue @ SwitchboardError::InvalidQueue, + /// constraint = verifier.load()?.enclave.enclave_signer == verifier_signer.key() @ SwitchboardError::InvalidEnclaveSigner, + /// )] + /// pub verifier: AccountLoader<'info, VerifierAccountData>, pub verifier: AccountInfo<'info>, // VerifierAccountData - #[account(signer)] - pub verifier_signer: AccountInfo<'info>, + + // #[account(signer)] + pub verifier_signer: Signer<'info>, + + /// #[account( + /// seeds = [ + /// PERMISSION_SEED, + /// attestation_queue.load()?.authority.as_ref(), + /// attestation_queue.key().as_ref(), + /// verifier.key().as_ref() + /// ], + /// bump = verifier_permission.load()?.bump, + /// )] + /// pub verifier_permission: AccountLoader<'info, AttestationPermissionAccountData>, pub verifier_permission: AccountInfo<'info>, // AttestationPermissionAccountData - pub escrow_wallet: AccountInfo<'info>, // SwitchboardWallet + + /// pub escrow_wallet: Box>, + pub escrow_wallet: AccountInfo<'info>, // SwitchboardWallet + + /// #[account( + /// mut, + /// constraint = escrow_token_wallet.is_native() + /// )] + /// pub escrow_token_wallet: Box>, #[account(mut)] pub escrow_token_wallet: AccountInfo<'info>, // TokenAccount + + /// #[account( + /// mut, + /// constraint = receiver.is_native() + /// )] + /// pub receiver: Box>, #[account(mut)] pub receiver: AccountInfo<'info>, // TokenAccount - pub attestation_queue: AccountInfo<'info>, // AttestationQueueAccountData + + /// pub attestation_queue: AccountLoader<'info, AttestationQueueAccountData>, + pub attestation_queue: AccountInfo<'info>, // AttestationQueueAccountData + + /// pub token_program: Program<'info, Token>, #[account(address = anchor_spl::token::ID)] pub token_program: AccountInfo<'info>, } @@ -36,6 +87,54 @@ impl Discriminator for FunctionVerify<'_> { const DISCRIMINATOR: [u8; 8] = [210, 108, 154, 138, 198, 14, 53, 191]; } +cfg_client! { + pub struct FunctionVerifyAccounts { + /// The FunctionAccount pubkey to verify. + pub function: Pubkey, + /// The pubkey of the enclave generated keypair that will be set after verification. + /// This keypair must sign any subsequent instructions to prove the instructions + /// were generated within an enclave. + pub function_enclave_signer: Pubkey, + /// The Function's SwitchboardWallet pubkey used to reward verifiers. + pub function_escrow: Pubkey, + + /// The VerifierAccount pubkey that is verifying the request. + pub verifier: Pubkey, + /// The VerifierAccount's enclave generated signer that must approve verifications. + pub verifier_enclave_signer: Pubkey, + /// The VerifierAccount's token wallet to receive a reward for verifying the request. + pub reward_receiver: Pubkey, + + /// The AttestationQueueAccount that the request is being verified for. + pub attestation_queue: Pubkey, + /// The AttestationQueueAccount's authority. Used to derive the VerifierAccount's permission account. + pub queue_authority: Pubkey, + } + impl ToAccountMetas for FunctionVerifyAccounts { + fn to_account_metas(&self, _: Option) -> Vec { + vec![ + AccountMeta::new(self.function, false), + AccountMeta::new_readonly(self.function_enclave_signer, true), + AccountMeta::new_readonly(self.verifier, false), + AccountMeta::new_readonly(self.verifier_enclave_signer, true), + AccountMeta::new_readonly( + AttestationPermissionAccountData::get_pda( + &self.queue_authority, + &self.attestation_queue, + &self.verifier + ), + false + ), + AccountMeta::new_readonly(self.function_escrow, false), + AccountMeta::new(crate::utils::find_associated_token_address(&self.function_escrow, &NativeMint::ID), false), + AccountMeta::new(self.reward_receiver, false), + AccountMeta::new_readonly(self.attestation_queue, false), + AccountMeta::new_readonly(anchor_spl::token::ID, false), + ] + } + } +} + impl<'info> FunctionVerify<'info> { pub fn get_instruction( &self, @@ -112,9 +211,9 @@ impl<'info> FunctionVerify<'info> { fn to_account_metas(&self, is_signer: Option) -> Vec { let mut account_metas = Vec::new(); account_metas.extend(self.function.to_account_metas(None)); - account_metas.extend(self.function_enclave_signer.to_account_metas(None)); + account_metas.extend(self.function_enclave_signer.to_account_metas(Some(true))); account_metas.extend(self.verifier.to_account_metas(None)); - account_metas.extend(self.verifier_signer.to_account_metas(None)); + account_metas.extend(self.verifier_signer.to_account_metas(Some(true))); account_metas.extend(self.verifier_permission.to_account_metas(None)); account_metas.extend(self.escrow_wallet.to_account_metas(None)); account_metas.extend(self.escrow_token_wallet.to_account_metas(None)); @@ -123,4 +222,20 @@ impl<'info> FunctionVerify<'info> { account_metas.extend(self.token_program.to_account_metas(None)); account_metas } + + cfg_client! { + pub fn build_ix( + accounts: &FunctionVerifyAccounts, + params: &FunctionVerifyParams, + ) -> Result { + + Ok( + crate::utils::build_ix( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + accounts, + params, + ) + ) + } + } } diff --git a/rust/switchboard-solana/src/attestation_program/instructions/mod.rs b/rust/switchboard-solana/src/attestation_program/instructions/mod.rs index 10a7ef374..df319e5c5 100644 --- a/rust/switchboard-solana/src/attestation_program/instructions/mod.rs +++ b/rust/switchboard-solana/src/attestation_program/instructions/mod.rs @@ -1,3 +1,9 @@ +pub mod attestation_permission_init; +pub use attestation_permission_init::*; + +pub mod attestation_permission_set; +pub use attestation_permission_set::*; + pub mod function_init; pub use function_init::*; @@ -16,6 +22,15 @@ pub use function_verify::*; pub mod function_close; pub use function_close::*; +pub mod attestation_queue_add_mrenclave; +pub use attestation_queue_add_mrenclave::*; + +pub mod attestation_queue_init; +pub use attestation_queue_init::*; + +pub mod routine_init; +pub use routine_init::*; + pub mod request_close; pub use request_close::*; @@ -34,6 +49,21 @@ pub use request_trigger::*; pub mod request_verify; pub use request_verify::*; +pub mod routine_verify; +pub use routine_verify::*; + +pub mod verifier_heartbeat; +pub use verifier_heartbeat::*; + +pub mod verifier_init; +pub use verifier_init::*; + +pub mod verifier_quote_rotate; +pub use verifier_quote_rotate::*; + +pub mod verifier_quote_verify; +pub use verifier_quote_verify::*; + pub mod wallet_init; pub use wallet_init::*; diff --git a/rust/switchboard-solana/src/attestation_program/instructions/request_close.rs b/rust/switchboard-solana/src/attestation_program/instructions/request_close.rs index ad7932c32..1be12be69 100644 --- a/rust/switchboard-solana/src/attestation_program/instructions/request_close.rs +++ b/rust/switchboard-solana/src/attestation_program/instructions/request_close.rs @@ -3,22 +3,57 @@ use crate::prelude::*; #[derive(Accounts)] #[instruction(params:FunctionRequestCloseParams)] pub struct FunctionRequestClose<'info> { + /// #[account( + /// mut, + /// close = sol_dest, + /// has_one = function, + /// has_one = escrow @ SwitchboardError::InvalidEscrow, + /// has_one = authority @ SwitchboardError::InvalidAuthority, + /// )] + /// pub request: Box>, #[account(mut)] pub request: AccountInfo<'info>, + /// CHECK: Only needs to sign if request.garbage_collection_slot has not elapsed pub authority: AccountInfo<'info>, + + /// #[account( + /// mut, + /// constraint = escrow.is_native() && escrow.owner == state.key() + /// )] + /// pub escrow: Box>, #[account(mut)] pub escrow: AccountInfo<'info>, + + /// pub function: AccountLoader<'info, FunctionAccountData>, /// CHECK: we need to load_mut and remove_request #[account(mut)] pub function: AccountInfo<'info>, + #[account(mut)] pub sol_dest: AccountInfo<'info>, + + /// #[account( + /// mut, + /// constraint = escrow_dest.is_native() && + /// escrow_dest.owner == request.authority // can only send funds to the account owner + /// )] + /// pub escrow_dest: Box>, #[account(mut)] pub escrow_dest: AccountInfo<'info>, + + /// #[account( + /// seeds = [STATE_SEED], + /// bump = state.load()?.bump, + /// )] + /// pub state: AccountLoader<'info, AttestationProgramState>, pub state: AccountInfo<'info>, + + /// pub token_program: Program<'info, Token>, #[account(address = anchor_spl::token::ID)] pub token_program: AccountInfo<'info>, + + /// pub system_program: Program<'info, System>, #[account(address = solana_program::system_program::ID)] pub system_program: AccountInfo<'info>, } diff --git a/rust/switchboard-solana/src/attestation_program/instructions/request_init_and_trigger.rs b/rust/switchboard-solana/src/attestation_program/instructions/request_init_and_trigger.rs index 2025905be..cd0ef8722 100644 --- a/rust/switchboard-solana/src/attestation_program/instructions/request_init_and_trigger.rs +++ b/rust/switchboard-solana/src/attestation_program/instructions/request_init_and_trigger.rs @@ -1,4 +1,6 @@ +use crate::cfg_client; use crate::prelude::*; +use crate::*; #[derive(Accounts)] #[instruction(params:FunctionRequestInitAndTriggerParams)] @@ -45,7 +47,7 @@ pub struct FunctionRequestInitAndTrigger<'info> { pub associated_token_program: AccountInfo<'info>, } -#[derive(Clone, AnchorSerialize, AnchorDeserialize)] +#[derive(Clone, AnchorSerialize, AnchorDeserialize, Default)] pub struct FunctionRequestInitAndTriggerParams { pub bounty: Option, pub slots_until_expiration: Option, @@ -65,6 +67,44 @@ impl Discriminator for FunctionRequestInitAndTrigger<'_> { const DISCRIMINATOR: [u8; 8] = [86, 151, 134, 172, 35, 218, 207, 154]; } +cfg_client! { + + pub struct FunctionRequestInitAndTriggerAccounts { + pub request: Pubkey, + pub authority: Pubkey, + /// The FunctionAccount for the request + pub function: Pubkey, + pub function_authority: Option, + /// The AttestationQueueAccount that the request is being verified for. + pub attestation_queue: Pubkey, + pub payer: Pubkey, + } + impl ToAccountMetas for FunctionRequestInitAndTriggerAccounts { + fn to_account_metas(&self, _: Option) -> Vec { + let func_authority = if let Some(function_authority) = &self.function_authority { + AccountMeta::new_readonly(*function_authority, true) + } else { + AccountMeta::new_readonly(SWITCHBOARD_ATTESTATION_PROGRAM_ID, false) + }; + + vec![ + AccountMeta::new(self.request, true), + AccountMeta::new_readonly(self.authority, true), + AccountMeta::new(self.function, false), + func_authority, + AccountMeta::new(find_associated_token_address(&self.request, &NativeMint::id()), false), + AccountMeta::new(NativeMint::id(), false), + AccountMeta::new_readonly(AttestationProgramState::get_pda(), false), + AccountMeta::new_readonly(self.attestation_queue, false), + AccountMeta::new(self.payer, true), + AccountMeta::new_readonly(anchor_lang::system_program::ID, false), + AccountMeta::new_readonly(anchor_spl::token::ID, false), + AccountMeta::new_readonly(anchor_spl::associated_token::ID, false), + ] + } + } +} + impl<'info> FunctionRequestInitAndTrigger<'info> { pub fn get_instruction( &self, @@ -237,4 +277,20 @@ impl<'info> FunctionRequestInitAndTrigger<'info> { account_metas.extend(self.associated_token_program.to_account_metas(None)); account_metas } + + cfg_client! { + pub fn build_ix( + accounts: &FunctionRequestInitAndTriggerAccounts, + params: &FunctionRequestInitAndTriggerParams, + ) -> Result { + + Ok( + crate::utils::build_ix( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + accounts, + params, + ) + ) + } + } } diff --git a/rust/switchboard-solana/src/attestation_program/instructions/request_verify.rs b/rust/switchboard-solana/src/attestation_program/instructions/request_verify.rs index 864aa4439..6c39df71f 100644 --- a/rust/switchboard-solana/src/attestation_program/instructions/request_verify.rs +++ b/rust/switchboard-solana/src/attestation_program/instructions/request_verify.rs @@ -1,26 +1,89 @@ +use crate::cfg_client; +use crate::find_associated_token_address; use crate::prelude::*; #[derive(Accounts)] #[instruction(params:FunctionRequestVerifyParams)] pub struct FunctionRequestVerify<'info> { + /// #[account( + /// mut, + /// has_one = function, + /// has_one = escrow @ SwitchboardError::InvalidEscrow, + /// )] + /// pub request: Box>, #[account(mut)] pub request: AccountInfo<'info>, // FunctionRequestAccount + #[account(signer)] pub function_enclave_signer: AccountInfo<'info>, // SystemProgram keypair + + /// #[account( + /// mut, + /// constraint = escrow.is_native() && escrow.owner == state.key() + /// )] + /// pub escrow: Box>, #[account(mut)] pub escrow: AccountInfo<'info>, // TokenAccount + + /// #[account( + /// mut, + /// has_one = attestation_queue @ SwitchboardError::InvalidQueue, + /// )] + /// pub function: AccountLoader<'info, FunctionAccountData>, #[account(mut)] pub function: AccountInfo<'info>, // FunctionAccount + + /// #[account( + /// mut, + /// constraint = escrow.is_native() && escrow.owner == state.key() + /// )] + /// pub function_escrow: Option>>, #[account(mut)] pub function_escrow: Option>, // TokenAccount + + /// #[account( + /// has_one = attestation_queue @ SwitchboardError::InvalidQueue, + /// constraint = + /// verifier_quote.load()?.enclave.enclave_signer == verifier_enclave_signer.key() + /// @ SwitchboardError::InvalidEnclaveSigner, + /// )] + /// pub verifier_quote: AccountLoader<'info, VerifierAccountData>, pub verifier_quote: AccountInfo<'info>, // VerifierAccountData + #[account(signer)] pub verifier_enclave_signer: AccountInfo<'info>, // SystemProgram keypair + + /// #[account( + /// seeds = [ + /// PERMISSION_SEED, + /// attestation_queue.load()?.authority.as_ref(), + /// attestation_queue.key().as_ref(), + /// verifier_quote.key().as_ref() + /// ], + /// bump = verifier_permission.load()?.bump, + /// )] + /// pub verifier_permission: AccountLoader<'info, AttestationPermissionAccountData>, pub verifier_permission: AccountInfo<'info>, // AttestationPermissionAccount - pub state: AccountInfo<'info>, // AttestationProgramState + + /// #[account( + /// seeds = [STATE_SEED], + /// bump = state.load()?.bump, + /// )] + /// pub state: AccountLoader<'info, AttestationProgramState>, + pub state: AccountInfo<'info>, // AttestationProgramState + + /// pub attestation_queue: AccountLoader<'info, AttestationQueueAccountData>, pub attestation_queue: AccountInfo<'info>, // AttestationQueueAccount + + /// #[account( + /// mut, + /// constraint = receiver.is_native() + /// )] + /// pub receiver: Box>, #[account(mut)] pub receiver: AccountInfo<'info>, // TokenAccount + + /// pub token_program: Program<'info, Token>, #[account(address = anchor_spl::token::ID)] pub token_program: AccountInfo<'info>, } @@ -44,6 +107,60 @@ impl Discriminator for FunctionRequestVerify<'_> { const DISCRIMINATOR: [u8; 8] = [179, 6, 88, 97, 232, 112, 143, 253]; } +cfg_client! { + + pub struct FunctionRequestVerifyAccounts { + /// The FunctionRequestAccount pubkey to verify. + pub request: Pubkey, + /// The pubkey of the enclave generated keypair that will be set after verification. + /// This keypair must sign any subsequent instructions to prove the instructions + /// were generated within an enclave. + pub function_enclave_signer: Pubkey, + + /// The FunctionAccount for the request being verified. + pub function: Pubkey, + /// The FunctionAccount escrow token wallet. Only used if the FunctionAccount has a request_fee set. + pub function_escrow_token_wallet: Option, + + /// The VerifierAccount pubkey that is verifying the request. + pub verifier: Pubkey, + /// The VerifierAccount's enclave generated signer that must approve verifications. + pub verifier_enclave_signer: Pubkey, + /// THe VerifierAccount's token wallet to receive a reward for verifying the request. + pub reward_receiver: Pubkey, + + /// The AttestationQueueAccount that the request is being verified for. + pub attestation_queue: Pubkey, + /// The AttestationQueueAccount's authority. Used to derive the VerifierAccount's permission account. + pub queue_authority: Pubkey, + } + impl ToAccountMetas for FunctionRequestVerifyAccounts { + fn to_account_metas(&self, _: Option) -> Vec { + vec![ + AccountMeta::new(self.request, false), + AccountMeta::new_readonly(self.function_enclave_signer, true), + AccountMeta::new(find_associated_token_address(&self.request, &NativeMint::id()), false), + AccountMeta::new(self.function, false), + AccountMeta::new(self.function_escrow_token_wallet.unwrap_or(SWITCHBOARD_ATTESTATION_PROGRAM_ID), false), + AccountMeta::new_readonly(self.verifier, false), + AccountMeta::new_readonly(self.verifier_enclave_signer, true), + AccountMeta::new_readonly( + AttestationPermissionAccountData::get_pda( + &self.queue_authority, + &self.attestation_queue, + &self.verifier + ), + false + ), + AccountMeta::new_readonly(AttestationProgramState::get_pda(), false), + AccountMeta::new_readonly(self.attestation_queue, false), + AccountMeta::new(self.reward_receiver, false), + AccountMeta::new_readonly(anchor_spl::token::ID, false), + ] + } + } +} + impl<'info> FunctionRequestVerify<'info> { pub fn get_instruction( &self, @@ -124,4 +241,19 @@ impl<'info> FunctionRequestVerify<'info> { account_metas.extend(self.token_program.to_account_metas(None)); account_metas } + + cfg_client! { + pub fn build_ix( + accounts: &FunctionRequestVerifyAccounts, + params: &FunctionRequestVerifyParams, + ) -> Result { + Ok( + crate::utils::build_ix( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + accounts, + params, + ) + ) + } + } } diff --git a/rust/switchboard-solana/src/attestation_program/instructions/routine_init.rs b/rust/switchboard-solana/src/attestation_program/instructions/routine_init.rs new file mode 100644 index 000000000..1dcc9cc50 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/instructions/routine_init.rs @@ -0,0 +1,164 @@ +use crate::prelude::*; + +#[derive(Accounts)] +#[instruction(params:FunctionRoutineInitParams)] +pub struct FunctionRoutineInit<'info> { + #[account( + mut, + signer, + owner = system_program.key(), + constraint = function.data_len() == 0 && function.lamports() == 0, + )] + pub routine: AccountInfo<'info>, + + /// CHECK: + pub authority: AccountInfo<'info>, + + #[account(mut)] + pub function: AccountInfo<'info>, + + #[account(signer)] + pub function_authority: Option>, + + /// CHECK: handle this manually because the PDA seed can vary + #[account(mut)] + pub escrow_wallet: AccountInfo<'info>, + + #[account(signer)] + pub escrow_wallet_authority: Option>, + + /// CHECK: handle this manually because the PDA seed can vary + #[account(mut)] + pub escrow_token_wallet: AccountInfo<'info>, + + #[account(address = anchor_spl::token::spl_token::native_mint::ID)] + pub mint: AccountInfo<'info>, + + pub attestation_queue: AccountInfo<'info>, + + #[account(mut, signer)] + pub payer: AccountInfo<'info>, + + #[account(address = solana_program::system_program::ID)] + pub system_program: AccountInfo<'info>, + #[account(address = anchor_spl::token::ID)] + pub token_program: AccountInfo<'info>, + #[account(address = anchor_spl::associated_token::ID)] + pub associated_token_program: AccountInfo<'info>, +} + +#[derive(Clone, AnchorSerialize, AnchorDeserialize)] +pub struct FunctionRoutineInitParams { + // Metadata + pub name: Option>, + pub metadata: Option>, + + // Fees + pub bounty: Option, + + // Execution + pub schedule: Vec, + pub max_container_params_len: Option, + pub container_params: Vec, +} + +impl InstructionData for FunctionRoutineInitParams {} + +impl Discriminator for FunctionRoutineInitParams { + const DISCRIMINATOR: [u8; 8] = [70, 25, 243, 23, 253, 78, 27, 169]; +} + +impl Discriminator for FunctionRoutineInit<'_> { + const DISCRIMINATOR: [u8; 8] = [70, 25, 243, 23, 253, 78, 27, 169]; +} + +impl<'info> FunctionRoutineInit<'info> { + pub fn get_instruction( + &self, + program_id: Pubkey, + params: &FunctionRoutineInitParams, + ) -> anchor_lang::Result { + let accounts = self.to_account_metas(None); + + let mut data: Vec = FunctionRoutineInit::discriminator().try_to_vec()?; + data.append(&mut params.try_to_vec()?); + + let instruction = Instruction::new_with_bytes(program_id, &data, accounts); + Ok(instruction) + } + + pub fn invoke( + &self, + program: AccountInfo<'info>, + params: &FunctionRoutineInitParams, + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key, params)?; + let account_infos = self.to_account_infos(); + + invoke(&instruction, &account_infos[..]) + } + + pub fn invoke_signed( + &self, + program: AccountInfo<'info>, + params: &FunctionRoutineInitParams, + signer_seeds: &[&[&[u8]]], + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key, params)?; + let account_infos = self.to_account_infos(); + + invoke_signed(&instruction, &account_infos[..], signer_seeds) + } + + fn to_account_infos(&self) -> Vec> { + let mut account_infos = Vec::new(); + account_infos.extend(self.routine.to_account_infos()); + account_infos.extend(self.authority.to_account_infos()); + account_infos.extend(self.function.to_account_infos()); + account_infos.extend(self.function_authority.to_account_infos()); + account_infos.extend(self.escrow_wallet.to_account_infos()); + account_infos.extend(self.escrow_wallet_authority.to_account_infos()); + account_infos.extend(self.escrow_token_wallet.to_account_infos()); + account_infos.extend(self.mint.to_account_infos()); + account_infos.extend(self.attestation_queue.to_account_infos()); + account_infos.extend(self.payer.to_account_infos()); + account_infos.extend(self.system_program.to_account_infos()); + account_infos.extend(self.token_program.to_account_infos()); + account_infos.extend(self.associated_token_program.to_account_infos()); + account_infos + } + + #[allow(unused_variables)] + fn to_account_metas(&self, is_signer: Option) -> Vec { + let mut account_metas = Vec::new(); + account_metas.extend(self.routine.to_account_metas(None)); + account_metas.extend(self.authority.to_account_metas(None)); + account_metas.extend(self.function.to_account_metas(None)); + if let Some(function_authority) = &self.function_authority { + account_metas.extend(function_authority.to_account_metas(None)); + } else { + account_metas.push(AccountMeta::new_readonly( + SWITCHBOARD_ATTESTATION_PROGRAM_ID, + false, + )); + } + account_metas.extend(self.escrow_wallet.to_account_metas(None)); + if let Some(escrow_wallet_authority) = &self.escrow_wallet_authority { + account_metas.extend(escrow_wallet_authority.to_account_metas(None)); + } else { + account_metas.push(AccountMeta::new_readonly( + SWITCHBOARD_ATTESTATION_PROGRAM_ID, + false, + )); + } + account_metas.extend(self.escrow_token_wallet.to_account_metas(None)); + account_metas.extend(self.mint.to_account_metas(None)); + account_metas.extend(self.attestation_queue.to_account_metas(None)); + account_metas.extend(self.payer.to_account_metas(None)); + account_metas.extend(self.system_program.to_account_metas(None)); + account_metas.extend(self.token_program.to_account_metas(None)); + account_metas.extend(self.associated_token_program.to_account_metas(None)); + + account_metas + } +} diff --git a/rust/switchboard-solana/src/attestation_program/instructions/routine_verify.rs b/rust/switchboard-solana/src/attestation_program/instructions/routine_verify.rs new file mode 100644 index 000000000..5f68321e4 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/instructions/routine_verify.rs @@ -0,0 +1,261 @@ +use crate::cfg_client; +use crate::find_associated_token_address; +use crate::prelude::*; + +#[derive(Accounts)] +#[instruction(params:FunctionRoutineVerifyParams)] +pub struct FunctionRoutineVerify<'info> { + /// #[account( + /// mut, + /// has_one = function, + /// has_one = escrow_wallet @ SwitchboardError::InvalidEscrow, + /// has_one = escrow_token_wallet @ SwitchboardError::InvalidEscrow, + /// )] + /// pub routine: Box>, + #[account(mut)] + pub routine: AccountInfo<'info>, // FunctionRequestAccount + + #[account(signer)] + pub function_enclave_signer: AccountInfo<'info>, // SystemProgram keypair + + /// #[account(mut)] + /// pub escrow_wallet: Box>, + #[account(mut)] + pub escrow_wallet: AccountInfo<'info>, // SwitchboardWallet + + // #[account( + // mut, + // constraint = escrow_token_wallet.is_native() + // )] + // pub escrow_token_wallet: Box>, + #[account(mut)] + pub escrow_token_wallet: AccountInfo<'info>, // TokenAccount + + /// #[account( + /// mut, + /// has_one = attestation_queue @ SwitchboardError::InvalidQueue, + /// )] + /// pub function: AccountLoader<'info, FunctionAccountData>, + #[account(mut)] + pub function: AccountInfo<'info>, // FunctionAccount + + /// #[account( + /// mut, + /// constraint = escrow.is_native() && escrow.owner == state.key() + /// )] + /// pub function_escrow_token_wallet: Option>>, + #[account(mut)] + pub function_escrow_token_wallet: Option>, // TokenAccount + + /// #[account( + /// has_one = attestation_queue @ SwitchboardError::InvalidQueue, + /// constraint = + /// verifier_quote.load()?.enclave.enclave_signer == verifier_enclave_signer.key() + /// @ SwitchboardError::InvalidEnclaveSigner, + /// )] + /// pub verifier_quote: AccountLoader<'info, VerifierAccountData>, + pub verifier_quote: AccountInfo<'info>, // VerifierAccountData + + #[account(signer)] + pub verifier_enclave_signer: AccountInfo<'info>, // SystemProgram keypair + + /// #[account( + /// seeds = [ + /// PERMISSION_SEED, + /// attestation_queue.load()?.authority.as_ref(), + /// attestation_queue.key().as_ref(), + /// verifier_quote.key().as_ref() + /// ], + /// bump = verifier_permission.load()?.bump, + /// )] + /// pub verifier_permission: AccountLoader<'info, AttestationPermissionAccountData>, + pub verifier_permission: AccountInfo<'info>, // AttestationPermissionAccount + + /// pub attestation_queue: AccountLoader<'info, AttestationQueueAccountData>, + pub attestation_queue: AccountInfo<'info>, // AttestationQueueAccount + + /// #[account( + /// mut, + /// constraint = receiver.is_native() + /// )] + /// pub receiver: Box>, + #[account(mut)] + pub receiver: AccountInfo<'info>, // TokenAccount + + /// pub token_program: Program<'info, Token>, + #[account(address = anchor_spl::token::ID)] + pub token_program: AccountInfo<'info>, +} + +#[derive(Clone, AnchorSerialize, AnchorDeserialize)] +pub struct FunctionRoutineVerifyParams { + pub observed_time: i64, + // TODO: should we verify this? + pub next_allowed_timestamp: i64, + pub error_code: u8, + pub mr_enclave: [u8; 32], + pub container_params_hash: [u8; 32], +} + +impl InstructionData for FunctionRoutineVerifyParams {} + +impl Discriminator for FunctionRoutineVerifyParams { + const DISCRIMINATOR: [u8; 8] = [138, 151, 43, 227, 196, 155, 245, 105]; +} + +impl Discriminator for FunctionRoutineVerify<'_> { + const DISCRIMINATOR: [u8; 8] = [138, 151, 43, 227, 196, 155, 245, 105]; +} + +cfg_client! { + + pub struct FunctionRoutineVerifyAccounts { + /// The FunctionRoutineAccount pubkey to verify. + pub routine: Pubkey, + /// The pubkey of the enclave generated keypair that will be set after verification. + /// This keypair must sign any subsequent instructions to prove the instructions + /// were generated within an enclave. + pub function_enclave_signer: Pubkey, + + pub escrow_wallet: Pubkey, + + /// The FunctionAccount for the request being verified. + pub function: Pubkey, + /// The FunctionAccount escrow token wallet. Only used if the FunctionAccount has a request_fee set. + pub function_escrow_token_wallet: Option, + + /// The VerifierAccount pubkey that is verifying the request. + pub verifier: Pubkey, + /// The VerifierAccount's enclave generated signer that must approve verifications. + pub verifier_enclave_signer: Pubkey, + /// THe VerifierAccount's token wallet to receive a reward for verifying the request. + pub reward_receiver: Pubkey, + + /// The AttestationQueueAccount that the request is being verified for. + pub attestation_queue: Pubkey, + /// The AttestationQueueAccount's authority. Used to derive the VerifierAccount's permission account. + pub queue_authority: Pubkey, + } + impl ToAccountMetas for FunctionRoutineVerifyAccounts { + fn to_account_metas(&self, _: Option) -> Vec { + vec![ + AccountMeta::new(self.routine, false), + AccountMeta::new_readonly(self.function_enclave_signer, true), + AccountMeta::new(self.escrow_wallet, false), + AccountMeta::new(find_associated_token_address(&self.escrow_wallet, &NativeMint::id()), false), + AccountMeta::new(self.function, false), + AccountMeta::new(self.function_escrow_token_wallet.unwrap_or(SWITCHBOARD_ATTESTATION_PROGRAM_ID), false), + AccountMeta::new_readonly(self.verifier, false), + AccountMeta::new_readonly(self.verifier_enclave_signer, true), + AccountMeta::new_readonly( + AttestationPermissionAccountData::get_pda( + &self.queue_authority, + &self.attestation_queue, + &self.verifier + ), + false + ), + AccountMeta::new_readonly(self.attestation_queue, false), + AccountMeta::new(self.reward_receiver, false), + AccountMeta::new_readonly(anchor_spl::token::ID, false), + ] + } + } +} + +impl<'info> FunctionRoutineVerify<'info> { + pub fn get_instruction( + &self, + program_id: Pubkey, + params: &FunctionRoutineVerifyParams, + ) -> anchor_lang::Result { + let accounts = self.to_account_metas(None); + + let mut data: Vec = FunctionRoutineVerify::discriminator().try_to_vec()?; + let mut param_vec: Vec = params.try_to_vec()?; + data.append(&mut param_vec); + + let instruction = Instruction::new_with_bytes(program_id, &data, accounts); + Ok(instruction) + } + + pub fn invoke( + &self, + program: AccountInfo<'info>, + params: &FunctionRoutineVerifyParams, + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key, params)?; + let account_infos = self.to_account_infos(); + + invoke(&instruction, &account_infos[..]) + } + + pub fn invoke_signed( + &self, + program: AccountInfo<'info>, + params: &FunctionRoutineVerifyParams, + signer_seeds: &[&[&[u8]]], + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key, params)?; + let account_infos = self.to_account_infos(); + + invoke_signed(&instruction, &account_infos[..], signer_seeds) + } + + fn to_account_infos(&self) -> Vec> { + let mut account_infos = Vec::new(); + account_infos.extend(self.routine.to_account_infos()); + account_infos.extend(self.function_enclave_signer.to_account_infos()); + account_infos.extend(self.escrow_wallet.to_account_infos()); + account_infos.extend(self.escrow_token_wallet.to_account_infos()); + account_infos.extend(self.function.to_account_infos()); + account_infos.extend(self.function_escrow_token_wallet.to_account_infos()); + account_infos.extend(self.verifier_quote.to_account_infos()); + account_infos.extend(self.verifier_enclave_signer.to_account_infos()); + account_infos.extend(self.verifier_permission.to_account_infos()); + account_infos.extend(self.attestation_queue.to_account_infos()); + account_infos.extend(self.receiver.to_account_infos()); + account_infos.extend(self.token_program.to_account_infos()); + account_infos + } + + #[allow(unused_variables)] + fn to_account_metas(&self, is_signer: Option) -> Vec { + let mut account_metas = Vec::new(); + account_metas.extend(self.routine.to_account_metas(None)); + account_metas.extend(self.function_enclave_signer.to_account_metas(None)); + account_metas.extend(self.escrow_wallet.to_account_metas(None)); + account_metas.extend(self.escrow_token_wallet.to_account_metas(None)); + account_metas.extend(self.function.to_account_metas(None)); + if let Some(function_escrow_token_wallet) = &self.function_escrow_token_wallet { + account_metas.extend(function_escrow_token_wallet.to_account_metas(None)); + } else { + account_metas.push(AccountMeta::new_readonly( + SWITCHBOARD_ATTESTATION_PROGRAM_ID, + false, + )); + } + account_metas.extend(self.verifier_quote.to_account_metas(None)); + account_metas.extend(self.verifier_enclave_signer.to_account_metas(None)); + account_metas.extend(self.verifier_permission.to_account_metas(None)); + account_metas.extend(self.attestation_queue.to_account_metas(None)); + account_metas.extend(self.receiver.to_account_metas(None)); + account_metas.extend(self.token_program.to_account_metas(None)); + account_metas + } + + cfg_client! { + pub fn build_ix( + accounts: &FunctionRoutineVerifyAccounts, + params: &FunctionRoutineVerifyParams, + ) -> Result { + Ok( + crate::utils::build_ix( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + accounts, + params, + ) + ) + } + } +} diff --git a/rust/switchboard-solana/src/attestation_program/instructions/verifier_heartbeat.rs b/rust/switchboard-solana/src/attestation_program/instructions/verifier_heartbeat.rs new file mode 100644 index 000000000..8ff099c33 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/instructions/verifier_heartbeat.rs @@ -0,0 +1,148 @@ +use crate::cfg_client; +use crate::prelude::*; + +#[derive(Accounts)] +#[instruction(params:VerifierHeartbeatParams)] +pub struct VerifierHeartbeat<'info> { + #[account(mut)] + pub verifier: AccountInfo<'info>, + + #[account(signer)] + pub verifier_signer: AccountInfo<'info>, + + #[account(mut)] + pub attestation_queue: AccountInfo<'info>, + + pub queue_authority: AccountInfo<'info>, + + #[account(mut)] + pub gc_node: AccountInfo<'info>, + + pub permission: AccountInfo<'info>, +} + +#[derive(Clone, AnchorSerialize, AnchorDeserialize)] +pub struct VerifierHeartbeatParams {} + +impl InstructionData for VerifierHeartbeatParams {} + +impl Discriminator for VerifierHeartbeatParams { + const DISCRIMINATOR: [u8; 8] = [25, 238, 221, 14, 250, 148, 0, 140]; +} + +impl Discriminator for VerifierHeartbeat<'_> { + const DISCRIMINATOR: [u8; 8] = [25, 238, 221, 14, 250, 148, 0, 140]; +} + +cfg_client! { + pub struct VerifierHeartbeatArgs { + pub verifier: Pubkey, + pub enclave_signer: Pubkey, + pub attestation_queue: Pubkey, + pub queue_authority: Pubkey, + pub gc_node: Pubkey, + } + pub struct VerifierHeartbeatAccounts { + pub verifier: Pubkey, + pub enclave_signer: Pubkey, + pub attestation_queue: Pubkey, + pub queue_authority: Pubkey, + pub gc_node: Pubkey, + pub permission: Pubkey, + } + impl ToAccountMetas for VerifierHeartbeatAccounts { + fn to_account_metas(&self, _: Option) -> Vec { + vec![ + AccountMeta::new(self.verifier, false), + AccountMeta::new_readonly(self.enclave_signer, true), + AccountMeta::new(self.attestation_queue, false), + AccountMeta::new_readonly(self.queue_authority, false), + AccountMeta::new(self.gc_node, false), + AccountMeta::new_readonly(self.permission, false), + ] + } + } +} + +impl<'info> VerifierHeartbeat<'info> { + pub fn get_instruction( + &self, + program_id: Pubkey, + params: VerifierHeartbeatParams, + ) -> anchor_lang::Result { + let accounts = self.to_account_metas(None); + + let mut data: Vec = VerifierHeartbeat::discriminator().try_to_vec()?; + data.append(&mut params.try_to_vec()?); + + let instruction = Instruction::new_with_bytes(program_id, &data, accounts); + Ok(instruction) + } + + pub fn invoke( + &self, + program: AccountInfo<'info>, + params: VerifierHeartbeatParams, + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key, params)?; + let account_infos = self.to_account_infos(); + + invoke(&instruction, &account_infos[..]) + } + + pub fn invoke_signed( + &self, + program: AccountInfo<'info>, + params: VerifierHeartbeatParams, + signer_seeds: &[&[&[u8]]], + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key, params)?; + let account_infos = self.to_account_infos(); + + invoke_signed(&instruction, &account_infos[..], signer_seeds) + } + + fn to_account_infos(&self) -> Vec> { + let mut account_infos = Vec::new(); + account_infos.extend(self.verifier.to_account_infos()); + account_infos.extend(self.verifier_signer.to_account_infos()); + account_infos.extend(self.attestation_queue.to_account_infos()); + account_infos.extend(self.queue_authority.to_account_infos()); + account_infos.extend(self.gc_node.to_account_infos()); + account_infos.extend(self.permission.to_account_infos()); + account_infos + } + + #[allow(unused_variables)] + fn to_account_metas(&self, is_signer: Option) -> Vec { + let mut account_metas = Vec::new(); + account_metas.extend(self.verifier.to_account_metas(None)); + account_metas.extend(self.verifier_signer.to_account_metas(None)); + account_metas.extend(self.attestation_queue.to_account_metas(None)); + account_metas.extend(self.queue_authority.to_account_metas(None)); + account_metas.extend(self.gc_node.to_account_metas(None)); + account_metas.extend(self.permission.to_account_metas(None)); + account_metas + } + + cfg_client! { + pub fn build_ix( + args: VerifierHeartbeatArgs + ) -> Result { + Ok( + crate::utils::build_ix( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + &VerifierHeartbeatAccounts { + verifier: args.verifier, + enclave_signer: args.enclave_signer, + attestation_queue: args.attestation_queue, + queue_authority: args.queue_authority, + gc_node: args.gc_node, + permission: AttestationPermissionAccountData::get_pda(&args.queue_authority, &args.attestation_queue, &args.verifier), + }, + &VerifierHeartbeatParams {}, + ) + ) + } + } +} diff --git a/rust/switchboard-solana/src/attestation_program/instructions/verifier_init.rs b/rust/switchboard-solana/src/attestation_program/instructions/verifier_init.rs new file mode 100644 index 000000000..17784bfab --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/instructions/verifier_init.rs @@ -0,0 +1,131 @@ +use crate::cfg_client; +use crate::prelude::*; + +#[derive(Accounts)] +#[instruction(params:VerifierInitParams)] +pub struct VerifierInit<'info> { + #[account( + init, + space = VerifierAccountData::size(), + payer = payer + )] + pub verifier: AccountInfo<'info>, + pub attestation_queue: AccountInfo<'info>, + pub queue_authority: AccountInfo<'info>, + pub authority: AccountInfo<'info>, + #[account(mut, signer)] + pub payer: AccountInfo<'info>, + pub system_program: AccountInfo<'info>, +} + +#[derive(Clone, AnchorSerialize, AnchorDeserialize)] +pub struct VerifierInitParams {} + +impl InstructionData for VerifierInitParams {} + +impl Discriminator for VerifierInitParams { + const DISCRIMINATOR: [u8; 8] = [197, 138, 116, 14, 24, 81, 9, 245]; +} + +impl Discriminator for VerifierInit<'_> { + const DISCRIMINATOR: [u8; 8] = [197, 138, 116, 14, 24, 81, 9, 245]; +} + +cfg_client! { + pub struct VerifierInitArgs { + pub verifier: Pubkey, + pub attestation_queue: Pubkey, + pub queue_authority: Pubkey, + pub payer: Pubkey, + } + + pub struct VerifierInitAccounts { + pub verifier: Pubkey, + pub attestation_queue: Pubkey, + pub queue_authority: Pubkey, + pub payer: Pubkey, + } + impl ToAccountMetas for VerifierInitAccounts { + fn to_account_metas(&self, _: Option) -> Vec { + vec![ + + AccountMeta::new(self.verifier, true), + AccountMeta::new(self.attestation_queue, false), + AccountMeta::new_readonly(self.queue_authority, false), // MAYBE + AccountMeta::new_readonly(self.payer, true), + AccountMeta::new(self.payer, true), + AccountMeta::new_readonly(solana_program::system_program::ID, false), + ] + } + } +} + +impl<'info> VerifierInit<'info> { + pub fn get_instruction(&self, program_id: Pubkey) -> anchor_lang::Result { + let accounts = self.to_account_metas(None); + + let instruction = + Instruction::new_with_bytes(program_id, &VerifierInit::discriminator(), accounts); + Ok(instruction) + } + + pub fn invoke(&self, program: AccountInfo<'info>) -> ProgramResult { + let instruction = self.get_instruction(*program.key)?; + let account_infos = self.to_account_infos(); + + invoke(&instruction, &account_infos[..]) + } + + pub fn invoke_signed( + &self, + program: AccountInfo<'info>, + signer_seeds: &[&[&[u8]]], + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key)?; + let account_infos = self.to_account_infos(); + + invoke_signed(&instruction, &account_infos[..], signer_seeds) + } + + fn to_account_infos(&self) -> Vec> { + let mut account_infos = Vec::new(); + account_infos.extend(self.verifier.to_account_infos()); + account_infos.extend(self.attestation_queue.to_account_infos()); + account_infos.extend(self.queue_authority.to_account_infos()); + account_infos.extend(self.authority.to_account_infos()); + account_infos.extend(self.payer.to_account_infos()); + account_infos.extend(self.system_program.to_account_infos()); + account_infos + } + + #[allow(unused_variables)] + fn to_account_metas(&self, is_signer: Option) -> Vec { + let mut account_metas = Vec::new(); + account_metas.extend(self.verifier.to_account_metas(None)); + account_metas.extend(self.attestation_queue.to_account_metas(None)); + account_metas.extend(self.queue_authority.to_account_metas(None)); + account_metas.extend(self.authority.to_account_metas(None)); + account_metas.extend(self.payer.to_account_metas(Some(true))); + account_metas.extend(self.system_program.to_account_metas(None)); + account_metas + } + + cfg_client! { + pub fn build_ix( + args: &VerifierInitArgs, + ) -> Result { + Ok( + crate::utils::build_ix( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + &VerifierInitAccounts { + verifier: args.verifier, + attestation_queue: args.attestation_queue, + queue_authority: args.queue_authority, + payer: args.payer, + }, + &VerifierInitParams {}, + ) + ) + } + } +} diff --git a/rust/switchboard-solana/src/attestation_program/instructions/verifier_quote_rotate.rs b/rust/switchboard-solana/src/attestation_program/instructions/verifier_quote_rotate.rs new file mode 100644 index 000000000..2454c9cfe --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/instructions/verifier_quote_rotate.rs @@ -0,0 +1,129 @@ +use crate::cfg_client; +use crate::prelude::*; + +#[derive(Accounts)] +#[instruction(params:VerifierQuoteRotateParams)] +pub struct VerifierQuoteRotate<'info> { + #[account(mut)] + pub verifier: AccountInfo<'info>, + + #[account(signer)] + pub authority: AccountInfo<'info>, + + /// CHECK: + pub enclave_signer: AccountInfo<'info>, + + #[account(mut)] + pub attestation_queue: AccountInfo<'info>, +} + +#[derive(Clone, AnchorSerialize, AnchorDeserialize)] +pub struct VerifierQuoteRotateParams { + pub registry_key: [u8; 64], +} + +impl InstructionData for VerifierQuoteRotateParams {} + +impl Discriminator for VerifierQuoteRotateParams { + const DISCRIMINATOR: [u8; 8] = [52, 93, 191, 90, 182, 82, 65, 197]; +} + +impl Discriminator for VerifierQuoteRotate<'_> { + const DISCRIMINATOR: [u8; 8] = [52, 93, 191, 90, 182, 82, 65, 197]; +} + +cfg_client! { + pub struct VerifierQuoteRotateAccounts { + pub verifier: Pubkey, + pub authority: Pubkey, + pub enclave_signer: Pubkey, + pub attestation_queue: Pubkey, + } + impl ToAccountMetas for VerifierQuoteRotateAccounts { + fn to_account_metas(&self, _: Option) -> Vec { + vec![ + AccountMeta::new(self.verifier, false), + AccountMeta::new_readonly(self.authority, true), + AccountMeta::new_readonly(self.enclave_signer, false), + AccountMeta::new(self.attestation_queue, false) + ] + } + } +} + +impl<'info> VerifierQuoteRotate<'info> { + pub fn get_instruction( + &self, + program_id: Pubkey, + registry_key: [u8; 64], + ) -> anchor_lang::Result { + let accounts = self.to_account_metas(None); + + let mut data: Vec = VerifierQuoteRotate::discriminator().try_to_vec()?; + data.append(&mut registry_key.try_to_vec()?); + + let instruction = Instruction::new_with_bytes(program_id, &data, accounts); + Ok(instruction) + } + + pub fn invoke(&self, program: AccountInfo<'info>, registry_key: [u8; 64]) -> ProgramResult { + let instruction = self.get_instruction(*program.key, registry_key)?; + let account_infos = self.to_account_infos(); + + invoke(&instruction, &account_infos[..]) + } + + pub fn invoke_signed( + &self, + program: AccountInfo<'info>, + registry_key: [u8; 64], + signer_seeds: &[&[&[u8]]], + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key, registry_key)?; + let account_infos = self.to_account_infos(); + + invoke_signed(&instruction, &account_infos[..], signer_seeds) + } + + fn to_account_infos(&self) -> Vec> { + let mut account_infos = Vec::new(); + account_infos.extend(self.verifier.to_account_infos()); + account_infos.extend(self.authority.to_account_infos()); + account_infos.extend(self.enclave_signer.to_account_infos()); + account_infos.extend(self.attestation_queue.to_account_infos()); + account_infos + } + + #[allow(unused_variables)] + fn to_account_metas(&self, is_signer: Option) -> Vec { + let mut account_metas = Vec::new(); + account_metas.extend(self.verifier.to_account_metas(None)); + account_metas.extend(self.authority.to_account_metas(None)); + account_metas.extend(self.enclave_signer.to_account_metas(None)); + account_metas.extend(self.attestation_queue.to_account_metas(None)); + account_metas + } + + cfg_client! { + pub fn build_ix( + verifier: &Pubkey, + verifier_authority: &Pubkey, + enclave_signer: &Pubkey, + attestation_queue: &Pubkey, + registry_key: [u8; 64], + ) -> Result { + Ok( + crate::utils::build_ix( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + &VerifierQuoteRotateAccounts { + verifier: *verifier, + authority: *verifier_authority, + enclave_signer: *enclave_signer, + attestation_queue: *attestation_queue, + }, + &VerifierQuoteRotateParams {registry_key}, + ) + ) + } + } +} diff --git a/rust/switchboard-solana/src/attestation_program/instructions/verifier_quote_verify.rs b/rust/switchboard-solana/src/attestation_program/instructions/verifier_quote_verify.rs new file mode 100644 index 000000000..ad3ecdaa0 --- /dev/null +++ b/rust/switchboard-solana/src/attestation_program/instructions/verifier_quote_verify.rs @@ -0,0 +1,140 @@ +use crate::cfg_client; +use crate::prelude::*; + +#[derive(Accounts)] +#[instruction(params:VerifierQuoteVerifyParams)] +pub struct VerifierQuoteVerify<'info> { + #[account(mut)] + pub quote: AccountInfo<'info>, + + pub verifier: AccountInfo<'info>, + + /// CHECK: + #[account(signer)] + pub enclave_signer: AccountInfo<'info>, + + #[account(mut)] + pub attestation_queue: AccountInfo<'info>, +} + +#[derive(Clone, AnchorSerialize, AnchorDeserialize)] +pub struct VerifierQuoteVerifyParams { + pub timestamp: i64, + pub mr_enclave: [u8; 32], + pub idx: u32, +} + +impl InstructionData for VerifierQuoteVerifyParams {} + +impl Discriminator for VerifierQuoteVerifyParams { + const DISCRIMINATOR: [u8; 8] = [73, 38, 235, 197, 78, 209, 141, 253]; +} + +impl Discriminator for VerifierQuoteVerify<'_> { + const DISCRIMINATOR: [u8; 8] = [73, 38, 235, 197, 78, 209, 141, 253]; +} + +cfg_client! { + pub struct VerifierQuoteVerifyArgs { + pub quote: Pubkey, + pub verifier: Pubkey, + pub enclave_signer: Pubkey, + pub attestation_queue: Pubkey, + pub timestamp: i64, + pub mr_enclave: [u8; 32], + pub idx: u32, + } + pub struct VerifierQuoteVerifyAccounts { + pub quote: Pubkey, + pub verifier: Pubkey, + pub enclave_signer: Pubkey, + pub attestation_queue: Pubkey, + } + impl ToAccountMetas for VerifierQuoteVerifyAccounts { + fn to_account_metas(&self, _: Option) -> Vec { + vec![ + AccountMeta::new(self.quote, false), + AccountMeta::new_readonly(self.verifier, false), + AccountMeta::new_readonly(self.enclave_signer, true), + AccountMeta::new(self.attestation_queue, false) + ] + } + } +} + +impl<'info> VerifierQuoteVerify<'info> { + pub fn get_instruction( + &self, + program_id: Pubkey, + params: VerifierQuoteVerifyParams, + ) -> anchor_lang::Result { + let accounts = self.to_account_metas(None); + + let mut data: Vec = VerifierQuoteVerify::discriminator().try_to_vec()?; + data.append(&mut params.try_to_vec()?); + + let instruction = Instruction::new_with_bytes(program_id, &data, accounts); + Ok(instruction) + } + + pub fn invoke( + &self, + program: AccountInfo<'info>, + params: VerifierQuoteVerifyParams, + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key, params)?; + let account_infos = self.to_account_infos(); + + invoke(&instruction, &account_infos[..]) + } + + pub fn invoke_signed( + &self, + program: AccountInfo<'info>, + params: VerifierQuoteVerifyParams, + signer_seeds: &[&[&[u8]]], + ) -> ProgramResult { + let instruction = self.get_instruction(*program.key, params)?; + let account_infos = self.to_account_infos(); + + invoke_signed(&instruction, &account_infos[..], signer_seeds) + } + + fn to_account_infos(&self) -> Vec> { + let mut account_infos = Vec::new(); + account_infos.extend(self.quote.to_account_infos()); + account_infos.extend(self.verifier.to_account_infos()); + account_infos.extend(self.enclave_signer.to_account_infos()); + account_infos.extend(self.attestation_queue.to_account_infos()); + account_infos + } + + #[allow(unused_variables)] + fn to_account_metas(&self, is_signer: Option) -> Vec { + let mut account_metas = Vec::new(); + account_metas.extend(self.quote.to_account_metas(None)); + account_metas.extend(self.verifier.to_account_metas(None)); + account_metas.extend(self.enclave_signer.to_account_metas(None)); + account_metas.extend(self.attestation_queue.to_account_metas(None)); + account_metas + } + + cfg_client! { + pub fn build_ix( + args: VerifierQuoteVerifyArgs + ) -> Result { + Ok( + crate::utils::build_ix( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + &VerifierQuoteVerifyAccounts { + quote: args.quote, + verifier: args.verifier, + enclave_signer: args.enclave_signer, + attestation_queue: args.attestation_queue, + }, + &VerifierQuoteVerifyParams {timestamp: args.timestamp, mr_enclave: args.mr_enclave, idx: args.idx}, + ) + ) + } + } +} diff --git a/rust/switchboard-solana/src/attestation_program/instructions/wallet_fund.rs b/rust/switchboard-solana/src/attestation_program/instructions/wallet_fund.rs index 120c7712a..f547ef8fc 100644 --- a/rust/switchboard-solana/src/attestation_program/instructions/wallet_fund.rs +++ b/rust/switchboard-solana/src/attestation_program/instructions/wallet_fund.rs @@ -99,7 +99,10 @@ impl<'info> WalletFund<'info> { if let Some(funder_wallet) = &self.funder_wallet { account_metas.extend(funder_wallet.to_account_metas(None)); } else { - account_metas.push(AccountMeta::new_readonly(crate::ID, false)); + account_metas.push(AccountMeta::new_readonly( + SWITCHBOARD_ATTESTATION_PROGRAM_ID, + false, + )); } account_metas.extend(self.funder.to_account_metas(None)); account_metas.extend(self.state.to_account_metas(None)); diff --git a/rust/switchboard-solana/src/attestation_program/instructions/wallet_init.rs b/rust/switchboard-solana/src/attestation_program/instructions/wallet_init.rs index 46730d222..1a112d300 100644 --- a/rust/switchboard-solana/src/attestation_program/instructions/wallet_init.rs +++ b/rust/switchboard-solana/src/attestation_program/instructions/wallet_init.rs @@ -1,4 +1,4 @@ -use crate::prelude::*; +use crate::{cfg_client, prelude::*}; #[derive(Accounts)] #[instruction(params:WalletInitParams)] @@ -15,7 +15,7 @@ pub struct WalletInit<'info> { pub token_wallet: AccountInfo<'info>, // TokenAccount #[account(mut, signer)] pub payer: AccountInfo<'info>, - pub state: AccountInfo<'info>, // AttestationProgramState + pub state: AccountInfo<'info>, // TODO: remove AttestationProgramState #[account(address = anchor_spl::token::ID)] pub token_program: AccountInfo<'info>, #[account(address = anchor_spl::associated_token::ID)] @@ -24,10 +24,11 @@ pub struct WalletInit<'info> { pub system_program: AccountInfo<'info>, } -#[derive(Clone, AnchorSerialize, AnchorDeserialize)] +#[derive(Clone, Default, AnchorSerialize, AnchorDeserialize)] pub struct WalletInitParams { pub name: Vec, - pub max_len: Option, + // TODO: remove + pub max_len: [u8; 4], } impl InstructionData for WalletInitParams {} @@ -44,19 +45,24 @@ impl<'info> WalletInit<'info> { pub fn get_instruction( &self, program_id: Pubkey, - params: &WalletInitParams, + name: &[u8], + // params: &WalletInitParams, ) -> anchor_lang::Result { let accounts = self.to_account_metas(None); let mut data: Vec = WalletInit::discriminator().try_to_vec()?; + let params = WalletInitParams { + name: name.to_vec(), + max_len: [0, 0, 0, 0], + }; data.append(&mut params.try_to_vec()?); let instruction = Instruction::new_with_bytes(program_id, &data, accounts); Ok(instruction) } - pub fn invoke(&self, program: AccountInfo<'info>, params: &WalletInitParams) -> ProgramResult { - let instruction = self.get_instruction(*program.key, params)?; + pub fn invoke(&self, program: AccountInfo<'info>, name: &[u8]) -> ProgramResult { + let instruction = self.get_instruction(*program.key, name)?; let account_infos = self.to_account_infos(); invoke(&instruction, &account_infos[..]) @@ -65,10 +71,10 @@ impl<'info> WalletInit<'info> { pub fn invoke_signed( &self, program: AccountInfo<'info>, - params: &WalletInitParams, + name: &[u8], signer_seeds: &[&[&[u8]]], ) -> ProgramResult { - let instruction = self.get_instruction(*program.key, params)?; + let instruction = self.get_instruction(*program.key, name)?; let account_infos = self.to_account_infos(); invoke_signed(&instruction, &account_infos[..], signer_seeds) @@ -104,4 +110,17 @@ impl<'info> WalletInit<'info> { account_metas.extend(self.system_program.to_account_metas(None)); account_metas } + + cfg_client! { + pub fn build_ix( + accounts: &SwitchboardWalletInitAccounts, + params: &WalletInitParams, + ) -> Result { + Ok(crate::utils::build_ix( + &SWITCHBOARD_ATTESTATION_PROGRAM_ID, + accounts, + params, + )) + } + } } diff --git a/rust/switchboard-solana/src/attestation_program/mod.rs b/rust/switchboard-solana/src/attestation_program/mod.rs index 18efa7a41..cb80ec9af 100644 --- a/rust/switchboard-solana/src/attestation_program/mod.rs +++ b/rust/switchboard-solana/src/attestation_program/mod.rs @@ -1,3 +1,8 @@ +use crate::cfg_client; + +mod error; +pub use error::SwitchboardError as SwitchboardAttestationError; + pub mod accounts; pub use accounts::*; @@ -6,3 +11,11 @@ pub use instructions::*; pub mod types; pub use types::*; + +pub mod events; +pub use events::*; + +cfg_client! { + mod client; + pub use client::*; +} diff --git a/rust/switchboard-solana/src/attestation_program/types.rs b/rust/switchboard-solana/src/attestation_program/types.rs index bb418d844..7462a7b39 100644 --- a/rust/switchboard-solana/src/attestation_program/types.rs +++ b/rust/switchboard-solana/src/attestation_program/types.rs @@ -29,7 +29,7 @@ impl Default for Quote { } } impl Quote { - pub fn reset_verification(&mut self) -> Result<()> { + pub fn reset_verification(&mut self) -> anchor_lang::Result<()> { if self.verification_status != VerificationStatus::VerificationOverride as u8 { self.verification_status = VerificationStatus::None.into(); } @@ -48,3 +48,242 @@ impl Quote { } } } + +pub trait ToU8 { + fn to_u8(&self) -> u8; +} +impl ToU8 for bool { + fn to_u8(&self) -> u8 { + if *self { + 1 + } else { + 0 + } + } +} +impl ToU8 for &bool { + fn to_u8(&self) -> u8 { + if **self { + 1 + } else { + 0 + } + } +} +pub trait ToBool { + fn to_bool(&self) -> bool; +} + +impl ToBool for u8 { + fn to_bool(&self) -> bool { + !matches!(*self, 0) + } +} +impl ToBool for &u8 { + fn to_bool(&self) -> bool { + !matches!(**self, 0) + } +} +/// An enum representing a boolean flag which can be locked. +/// Byte #0: 0 = Disabled, 1 = Enabled +/// Byte #1: 0 = Unlocked, 1 = Locked +#[repr(u8)] +#[derive( + Copy, Clone, Default, Debug, Eq, PartialEq, AnchorSerialize, AnchorDeserialize, InitSpace, +)] +pub enum BoolWithLock { + #[default] + Disabled, // 0 : 00000000 + Enabled, // 1 : 00000001 : 1 << 0 + DisabledLocked, // 2 : 00000010 : 1 << 1 + EnabledLocked, // 3 : 00000011 +} +impl BoolWithLock { + pub fn is_enabled(&self) -> bool { + let byte: u8 = (*self).into(); + byte & (1 << 0) != 0 + } + + pub fn is_disabled(&self) -> bool { + !self.is_enabled() + } + + pub fn is_locked(&self) -> bool { + let byte: u8 = (*self).into(); + byte & (1 << 1) != 0 + } + + /// Converts boolean flags into a bitfield enum value. + /// + /// # Arguments + /// + /// * `is_enabled` - A boolean flag indicating if the feature is enabled. + /// * `is_locked` - A boolean flag indicating if the feature is locked. + /// + /// # Returns + /// + /// A bitfield enum value representing the input flags. + fn from_flags(is_enabled: bool, is_locked: Option) -> Self { + let mut value: u8 = 0; + + if is_enabled { + value |= 1 << 0; // Set the 0th bit if enabled + } + + if is_locked.unwrap_or_default() { + value |= 1 << 1; // Set the 1st bit if locked + } + + value.into() + } + + /// Asserts that the configuration parameter is unlocked. + pub fn assert_unlocked(&self) -> anchor_lang::Result<()> { + if self.is_locked() { + return Err(error!(SwitchboardError::ConfigParameterLocked)); + } + + Ok(()) + } + + /// Updates the value of the enum with a new value. + /// + /// # Arguments + /// + /// * `new_value` - A reference to a `BoolWithLock` struct containing the new value. + /// + /// # Errors + /// + /// Returns an error if the enum is locked and an update attempt is made. + /// + /// # Returns + /// + /// Returns `Ok(())` if the update is successful. + pub fn update(&mut self, is_enabled: bool, is_locked: Option) -> anchor_lang::Result<()> { + self.assert_unlocked()?; + + let new_value = Self::from_flags(is_enabled, is_locked); + + *self = new_value; + + Ok(()) + } + + /// Locks the enum value for further updates. No action taken if the enum is already locked. + pub fn lock(&mut self) -> anchor_lang::Result<()> { + if self.is_locked() { + return Ok(()); + } + + let mut val: u8 = (*self).into(); + val |= 1 << 1; + + *self = val.into(); + + Ok(()) + } +} +impl From for u8 { + fn from(value: BoolWithLock) -> Self { + match value { + BoolWithLock::Disabled => 0, + BoolWithLock::Enabled => 1, + BoolWithLock::DisabledLocked => 2, + BoolWithLock::EnabledLocked => 3, + } + } +} +impl From for BoolWithLock { + fn from(value: u8) -> Self { + match value { + 1 => BoolWithLock::Enabled, + 2 => BoolWithLock::DisabledLocked, + 3 => BoolWithLock::EnabledLocked, + _ => BoolWithLock::default(), + } + } +} + +/// An enum representing a heirarchy of resources that can modify a field. +#[repr(u8)] +#[derive( + Copy, Clone, Default, Debug, Eq, PartialEq, AnchorSerialize, AnchorDeserialize, InitSpace, +)] +pub enum ResourceLevel { + #[default] + None = 0, // 0 + /// The resource's authority has set this value. + Authority, + /// The resource function's authority has set this value. + Function, + /// The resource queue's authority has set this value. + Queue, +} +impl PartialOrd for ResourceLevel { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} +impl Ord for ResourceLevel { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + (*self as u8).cmp(&(*other as u8)) + } +} +impl From for u8 { + fn from(value: ResourceLevel) -> Self { + match value { + ResourceLevel::Authority => 1, + ResourceLevel::Function => 2, + ResourceLevel::Queue => 3, + _ => 0, + } + } +} +impl From for ResourceLevel { + fn from(value: u8) -> Self { + match value { + 1 => ResourceLevel::Authority, + 2 => ResourceLevel::Function, + 3 => ResourceLevel::Queue, + _ => ResourceLevel::default(), + } + } +} +impl From for bool { + fn from(value: ResourceLevel) -> Self { + !matches!(value, ResourceLevel::None) + } +} +impl ResourceLevel { + pub fn update( + &mut self, + access_level: &ResourceLevel, + reset: Option, + ) -> anchor_lang::Result<()> { + let target_value = if reset.unwrap_or_default() { + ResourceLevel::None + } else { + *access_level + }; + + // No action needed + if self == &target_value { + return Ok(()); + } + + // If insufficient access to change the value + if self > &mut access_level.clone() { + msg!( + "ResourceLevel: curr ({:?}), target ({:?}), access_level ({:?})", + self, + target_value, + access_level + ); + return Err(error!(SwitchboardError::IllegalExecuteAttempt)); + } + + *self = target_value; + + Ok(()) + } +} diff --git a/rust/switchboard-solana/src/client/function_runner.rs b/rust/switchboard-solana/src/client/function_runner.rs index cb6caca0a..a1758876d 100644 --- a/rust/switchboard-solana/src/client/function_runner.rs +++ b/rust/switchboard-solana/src/client/function_runner.rs @@ -3,7 +3,6 @@ use anchor_lang::solana_program::instruction::Instruction; use anchor_lang::solana_program::message::Message; use anchor_lang::solana_program::pubkey::Pubkey; use anchor_lang::AnchorDeserialize; -use hex; use sgx_quote::Quote; use solana_client::rpc_client::RpcClient; use solana_sdk::commitment_config::CommitmentConfig; @@ -11,39 +10,63 @@ use solana_sdk::signer::keypair::Keypair; use std::result::Result; use std::str::FromStr; use std::sync::Arc; -use switchboard_common::ChainResultInfo::Solana; -use switchboard_common::SOLFunctionResult; -use switchboard_common::SolanaFunctionEnvironment; -/// A management object for structured runtime for Switchboard Functions on -/// solana. Inititlizing this object will load all required variables -/// from the runtime to execute and sign an output transaction to be verified -/// and committed by the switchboard network. +use switchboard_common::SolanaFunctionEnvironment; +use switchboard_common::{ChainResultInfo::Solana, SolanaFunctionResult}; + +/// An object containing the context to execute a Switchboard Function. +/// Inititlizing this object will load all required variables from the runtime +/// to execute and sign an output transaction to be verified and committed by +/// the switchboard network. +/// +/// ``` +/// use switchboard_solana::FunctionRunner; +/// +/// let runner = FunctionRunner::from_env(None)?; +/// ``` #[derive(Clone)] pub struct FunctionRunner { + /// The type of Switchboard function being run. + pub request_type: SolanaFunctionRequestType, + /// The Solana RPC client to make rpc requests. pub client: Arc, + /// The enclave generated signer for this function run. signer_keypair: Arc, + /// The pubkey of the enclave generated signer. pub signer: Pubkey, // required to run + /// The FunctionAccount pubkey being run. pub function: Pubkey, + /// The pubkey of the account that will pay for emitted transactions. pub payer: Pubkey, + /// The VerifierAccount that will verify this function run. pub verifier: Pubkey, + /// The VerifierAccount's specified reward receiver. pub reward_receiver: Pubkey, // can be manually populated from client if missing + /// The hex encoded FunctionAccountData, used to speed up RPC calls. pub function_data: Option>, + /// The pubkey of the VerifierAccount's enclave signer. pub verifier_enclave_signer: Option, pub queue_authority: Option, + // only used for routines + pub function_routine_key: Option, + pub function_routine_data: Option>, + // only used for requests pub function_request_key: Option, pub function_request_data: Option>, // convienence for building ixns + /// The AttestationQueueAccount for this request. pub attestation_queue: Option, + /// The Switchboard State pubkey. pub switchboard_state: Pubkey, + /// The Attestation program id. pub switchboard: Pubkey, } @@ -61,7 +84,8 @@ impl std::fmt::Display for FunctionRunner { } impl FunctionRunner { - pub fn new_with_client(client: RpcClient) -> Result { + /// Create a new FunctionRunner instance with a provided RPC client. + pub fn new_with_client(client: RpcClient) -> Result { let signer_keypair = generate_signer(); let signer = signer_to_pubkey(signer_keypair.clone())?; @@ -76,75 +100,59 @@ impl FunctionRunner { let mut attestation_queue: Option = None; // can be manually populated from client if missing - let function_data: Option> = - if let Some(function_data_encoded) = env.function_data.as_ref() { - // match bytemuck::try_from_bytes(&) - match bytemuck::try_from_bytes::( - &hex::decode(function_data_encoded).unwrap_or_default(), - ) { - Ok(function_data) => { - attestation_queue = Some(function_data.attestation_queue); - if function_data != &FunctionAccountData::default() { - Some(Box::new(*function_data)) - } else { - None - } - } - Err(_) => None, - } - } else { - None - }; + // let function_data: Option> = if env.function_data.is_empty() { + // None + // } else { + // match bytemuck::try_from_bytes::( + // &hex::decode(env.function_data).unwrap_or_default(), + // ) { + // Ok(function_data) => { + // if function_data != &FunctionAccountData::default() { + // Some(Box::new(*function_data)) + // } else { + // None + // } + // } + // Err(_) => None, + // } + // }; + let fn_hex = env.function_data; + let fn_raw = hex::decode(fn_hex).unwrap(); + let function_data = Some(Box::new(*bytemuck::try_from_bytes::(&fn_raw).unwrap())); + attestation_queue = Some(function_data.as_ref().unwrap().attestation_queue); + let verifier_enclave_signer: Option = - if let Some(verifier_enclave_signer) = env.verifier_enclave_signer { - match Pubkey::from_str(&verifier_enclave_signer) { - Ok(verifier_enclave_signer) => { - if verifier_enclave_signer != Pubkey::default() { - Some(verifier_enclave_signer) - } else { - None + parse_optional_pubkey(&env.verifier_enclave_signer); + let queue_authority: Option = parse_optional_pubkey(&env.queue_authority); + + // only used for routines + let function_routine_key: Option = parse_optional_pubkey(&env.function_routine_key); + let function_routine_data: Option> = + if env.function_routine_data.is_empty() { + None + } else { + match FunctionRoutineAccountData::try_from_slice( + &hex::decode(&env.function_routine_data).unwrap_or_default(), + ) { + Ok(function_routine_data) => { + if attestation_queue.is_none() { + attestation_queue = Some(function_routine_data.attestation_queue); } + + Some(Box::new(function_routine_data)) } Err(_) => None, } - } else { - None }; - let queue_authority: Option = if let Some(queue_authority) = env.queue_authority { - match Pubkey::from_str(&queue_authority) { - Ok(queue_authority) => { - if queue_authority != Pubkey::default() { - Some(queue_authority) - } else { - None - } - } - Err(_) => None, - } - } else { - None - }; // only used for requests - let function_request_key: Option = - if let Some(function_request_key) = env.function_request_key { - match Pubkey::from_str(&function_request_key) { - Ok(function_request_key) => { - if function_request_key != Pubkey::default() { - Some(function_request_key) - } else { - None - } - } - Err(_) => None, - } - } else { - None - }; + let function_request_key: Option = parse_optional_pubkey(&env.function_request_key); let function_request_data: Option> = - if let Some(function_request_data_encoded) = env.function_request_data.as_ref() { + if env.function_request_data.is_empty() { + None + } else { match FunctionRequestAccountData::try_from_slice( - &hex::decode(function_request_data_encoded).unwrap_or_default(), + &hex::decode(&env.function_request_data).unwrap_or_default(), ) { Ok(function_request_data) => { if attestation_queue.is_none() { @@ -155,20 +163,32 @@ impl FunctionRunner { } Err(_) => None, } - } else { - None }; let switchboard: Pubkey = load_env_pubkey("SWITCHBOARD").unwrap_or(SWITCHBOARD_ATTESTATION_PROGRAM_ID); + let switchboard_state = AttestationProgramState::get_program_pda(Some(switchboard)); + // The type of Switchboard request being executed. + let request_type: SolanaFunctionRequestType = + if let Some(function_routine_key) = function_routine_key { + SolanaFunctionRequestType::Routine(function_routine_key.to_bytes().into()) + } else if let Some(function_request_key) = function_request_key { + SolanaFunctionRequestType::Request(function_request_key.to_bytes().into()) + } else { + SolanaFunctionRequestType::Function(function.to_bytes().into()) + }; + Ok(Self { + request_type, client: Arc::new(client), signer_keypair, signer, function, function_data, + function_routine_key, + function_routine_data, function_request_key, function_request_data, payer, @@ -182,65 +202,143 @@ impl FunctionRunner { }) } - pub fn assert_mr_enclave(&self) -> Result<(), SwitchboardClientError> { - if let Some(function_data) = self.function_data.clone() { - let quote_raw = Gramine::generate_quote(&self.signer.to_bytes()).unwrap_or_default(); - if let Ok(quote) = Quote::parse("e_raw) { - let mr_enclave: MrEnclave = quote.isv_report.mrenclave.try_into().unwrap(); - if !function_data.mr_enclaves.contains(&mr_enclave) { - return Err(SwitchboardClientError::MrEnclaveMismatch); - } - } - } - Ok(()) - } - - pub fn new( - url: &str, - commitment: Option, - ) -> Result { + /// Create a new FunctionRunner from an RPC endpoint and commitment level. + pub fn new(url: &str, commitment: Option) -> Result { Self::new_with_client(RpcClient::new_with_commitment( url, commitment.unwrap_or_default(), )) } + /// Create a new FunctionRunner for a given cluster. pub fn new_from_cluster( cluster: Cluster, commitment: Option, - ) -> Result { + ) -> Result { Self::new(cluster.url(), commitment) } - /// Loads the FunctionRunner from runtime settings - pub fn from_env(commitment: Option) -> Result { - let cluster = Cluster::from_str(&std::env::var("CLUSTER").unwrap()).unwrap(); + /// Loads the FunctionRunner from runtime settings. + pub fn from_env(commitment: Option) -> Result { + let cluster = + Cluster::from_str(&std::env::var("CLUSTER").unwrap_or("mainnet".to_string())).unwrap(); Self::new_from_cluster(cluster, commitment) } + pub fn is_scheduled_function(&self) -> bool { + matches!(self.request_type, SolanaFunctionRequestType::Function(_)) + } + + pub fn is_routine(&self) -> bool { + matches!(self.request_type, SolanaFunctionRequestType::Routine(_)) + } + + pub fn is_request(&self) -> bool { + matches!(self.request_type, SolanaFunctionRequestType::Request(_)) + } + + /// Load the function parameters for the given function run. + pub async fn load_params(&mut self) -> Result, SbError> { + match self.request_type { + SolanaFunctionRequestType::Routine(_) => { + let routine = self.load_routine_data().await?; + let params = routine.container_params.clone(); + + if self.function_routine_data.is_none() { + self.function_routine_data = Some(routine); + } + + Ok(params) + } + SolanaFunctionRequestType::Request(_) => { + let request = self.load_request_data().await?; + let params = request.container_params.clone(); + + if self.function_request_data.is_none() { + self.function_request_data = Some(request); + } + + Ok(params) + } + // TODO: deprecate this path + SolanaFunctionRequestType::Function(_) => { + let function_data = self.load_function_data().await?; + let params = function_data.default_container_params.to_vec(); + + if self.function_data.is_none() { + self.function_data = Some(function_data); + } + + Ok(params) + } + } + } + + /// Loads the parameters from the client and deserializes them into a given type using serde. + /// + /// # Example + /// + /// ``` + /// use switchboard_solana::client::FunctionRunner; + /// + /// #[derive(serde::Deserialize)] + /// struct MyParams { + /// name: String, + /// age: u8, + /// } + /// + /// async fn my_function() -> Result<(), switchboard_solana::SbError> { + /// let mut runner = FunctionRunner::new(); + /// let params: MyParams = runner.load_serde_params().await?; + /// println!("Name: {}, Age: {}", params.name, params.age); + /// Ok(()) + /// } + /// ``` + pub async fn load_serde_params( + &mut self, + ) -> Result { + let bytes: Vec = self.load_params().await?; + let decoded: T = serde_json::from_slice(&bytes[..])?; + Ok(decoded) + } + + /// Assert that a [`FunctionAccountData`] contains the generated MrEnclave in its config + pub fn assert_mr_enclave(&self) -> Result<(), SbError> { + // pub fn assert_mr_enclave(&self, quote: Option>) -> Result<(), SbError> { + // let function_data = self.load_function_data().await?; + // let quote_raw = + // quote.unwrap_or(Gramine::generate_quote(&self.signer.to_bytes()).unwrap_or_default()); + + if let Some(function_data) = self.function_data.clone() { + let quote_raw = Gramine::generate_quote(&self.signer.to_bytes()).unwrap_or_default(); + if let Ok(quote) = Quote::parse("e_raw) { + let mr_enclave: MrEnclave = quote.isv_report.mrenclave.try_into().unwrap(); + if !function_data.mr_enclaves.contains(&mr_enclave) { + return Err(SbError::MrEnclaveMismatch); + } + } + } + Ok(()) + } + /// Loads the queue authority provided by the QUEUE_AUTHORITY environment /// variable async fn load_queue_authority( &self, attestation_queue_pubkey: Pubkey, - ) -> Result { + ) -> Result { let queue_authority = self.queue_authority.unwrap_or_default(); if queue_authority != Pubkey::default() { return Ok(queue_authority); } msg!( - "queue_authority missing! {}", - std::env::var("QUEUE_AUTHORITY").unwrap_or("N/A".to_string()) - ); - - msg!( - "fetching attestation_queue account {}", + "QUEUE_AUTHORITY is missing - Fetching attestation_queue account {}", attestation_queue_pubkey ); - match AttestationQueueAccountData::fetch(&self.client, attestation_queue_pubkey).await { - Err(error) => Err(SwitchboardClientError::CustomMessage(format!( + match AttestationQueueAccountData::fetch(&self.client, attestation_queue_pubkey) { + Err(error) => Err(SbError::CustomMessage(format!( "failed to fetch attestation_queue {}: {}", attestation_queue_pubkey, error ))), @@ -248,6 +346,8 @@ impl FunctionRunner { } } + /// Returns the associated token address for a given owner and mint. + /// If the mint is not provided, the native SOL mint is used. pub fn get_associated_token_address(owner: Pubkey, mint: Option) -> Pubkey { anchor_spl::associated_token::get_associated_token_address( &owner, @@ -257,24 +357,19 @@ impl FunctionRunner { /// Loads the oracle signing key provided by the VERIFIER_ENCLAVE_SIGNER /// environment variable - async fn load_verifier_signer( - &self, - verifier_pubkey: Pubkey, - ) -> Result { + async fn load_verifier_signer(&self, verifier_pubkey: Pubkey) -> Result { let verifier_enclave_signer = self.verifier_enclave_signer.unwrap_or_default(); if verifier_enclave_signer != Pubkey::default() { return Ok(verifier_enclave_signer); } msg!( - "verifier_enclave_signer missing! {}", - std::env::var("VERIFIER_ENCLAVE_SIGNER").unwrap_or("N/A".to_string()) + "VERIFIER_ENCLAVE_SIGNER is missing - Fetching verifier account {}", + verifier_pubkey ); - msg!("fetching verifier account {}", verifier_pubkey); - - match VerifierAccountData::fetch(&self.client, verifier_pubkey).await { - Err(error) => Err(SwitchboardClientError::CustomMessage(format!( + match VerifierAccountData::fetch(&self.client, verifier_pubkey) { + Err(error) => Err(SbError::CustomMessage(format!( "failed to fetch verifier {}: {}", verifier_pubkey, error ))), @@ -282,56 +377,184 @@ impl FunctionRunner { } } + async fn build_verify_ixn( + &self, + mr_enclave: [u8; 32], + error_code: u8, + ) -> Result { + match self.request_type { + SolanaFunctionRequestType::Routine(_) => { + self.build_fn_routine_verify_ixn(mr_enclave, error_code) + .await + } + SolanaFunctionRequestType::Request(_) => { + self.build_fn_request_verify_ixn(mr_enclave, error_code) + .await + } + // TODO: deprecate this path + SolanaFunctionRequestType::Function(_) => { + self.build_fn_verify_ixn(mr_enclave, error_code).await + } + } + } + + /// Generates a FunctionResult object to be emitted at the end of this + /// function run. This function result will be used be the quote verification + /// sidecar to verify the output was run inside the function's enclave + /// and sign the transaction to send back on chain. + pub async fn get_function_result( + &self, + mut ixs: Vec, + error_code: u8, + ) -> Result { + // Generate the SGX quote from the enclave + // TODO: should we set a flag if this is a simulation? + let quote_raw = Gramine::generate_quote(&self.signer.to_bytes()).unwrap_or_default(); + let mut mr_enclave: MrEnclave = Default::default(); + if quote_raw.is_empty() { + println!("WARNING!: Reading from enclave failed! If you are testing, this is expected behavior."); + } else { + let quote = Quote::parse("e_raw).unwrap(); + mr_enclave = quote.isv_report.mrenclave.try_into().unwrap(); + } + + // Build serialized transaction + let verify_ixn: Instruction = self.build_verify_ixn(mr_enclave, error_code).await?; + ixs.insert(0, verify_ixn); + let message = Message::new(&ixs, Some(&self.payer)); + let blockhash = self.client.get_latest_blockhash().unwrap_or_default(); + let mut tx = solana_sdk::transaction::Transaction::new_unsigned(message); + tx.partial_sign(&[self.signer_keypair.as_ref()], blockhash); + let serialized_tx = bincode::serialize(&tx).unwrap(); + + let request_hash = if self.is_request() { + solana_program::hash::hash( + &self + .function_request_data + .as_ref() + .unwrap() + .container_params, + ) + .to_bytes() + .to_vec() + } else if self.is_routine() { + solana_program::hash::hash( + &self + .function_routine_data + .as_ref() + .unwrap() + .container_params, + ) + .to_bytes() + .to_vec() + } else { + let function_data = self.load_function_data().await?; + solana_program::hash::hash(&function_data.as_ref().default_container_params) + .to_bytes() + .to_vec() + }; + + Ok(FunctionResult::V1(FunctionResultV1 { + quote: quote_raw, + signer: self.signer.to_bytes().into(), + signature: vec![], + chain_result_info: Solana(SolanaFunctionResult::V1(SolanaFunctionResultV1 { + fn_key: self.function.to_bytes().into(), + serialized_tx, + request_hash, + request_type: self.request_type.clone(), + })), + error_code, + })) + } + + /// Emits a serialized FunctionResult object to send to the quote verification + /// sidecar. + pub async fn emit(&self, ixs: Vec) -> Result<(), SbError> { + self.get_function_result(ixs, 0) + .await + .map_err(|e| SbError::CustomMessage(format!("failed to get verify ixn: {}", e))) + .unwrap() + .emit(); + + Ok(()) + } + + /// Emit an error and relay the error code on-chain for your downstream program to handle. + pub async fn emit_error(&self, error_code: u8) -> Result<(), SbError> { + self.get_function_result(vec![], error_code) + .await + .unwrap() + .emit(); + Ok(()) + } + + ////////////////////////////////////////////////////////////////////////////// + /// Function Methods + ////////////////////////////////////////////////////////////////////////////// + /// Loads the data of the function account provided by the FUNCTION_DATA /// environment variable. - pub async fn load_function_data( - &self, - ) -> Result, SwitchboardClientError> { + pub async fn load_function_data(&self) -> Result, SbError> { if let Some(function_data) = self.function_data.as_ref() { if **function_data != FunctionAccountData::default() { return Ok(function_data.clone()); } } - msg!("fetching function account {}", self.function); + msg!( + "FUNCTION_DATA is missing - Fetching function account {}", + self.function + ); - match FunctionAccountData::fetch(&self.client, self.function).await { - Ok(function_data) => Ok(Box::new(function_data)), - Err(error) => Err(SwitchboardClientError::CustomMessage(format!( - "failed to fetch function {}: {}", - self.function, error - ))), - } + FunctionAccountData::fetch(&self.client, self.function) + .map_err(|error| { + SbError::CustomMessage(format!( + "failed to fetch function {}: {}", + self.function, error + )) + }) + .and_then(|function_data| { + if function_data != FunctionAccountData::default() { + Ok(Box::new(function_data)) + } else { + Err(SbError::CustomMessage(format!( + "function account {} is empty", + self.function + ))) + } + }) } - /// If this execution is tied to a function request, load the data of the - /// execution function request account. - pub async fn load_request_data( - &self, - ) -> Result, SwitchboardClientError> { - let function_request_key = self.function_request_key.unwrap_or_default(); - if function_request_key == Pubkey::default() { - return Err(SwitchboardClientError::CustomMessage( - "function_request_key is missing but required to fetch function request account" - .to_string(), - )); + /// Load all of the accounts + + pub async fn load_accounts(&mut self) -> Result<(), SbError> { + if self.is_scheduled_function() { + self.load_function().await?; } - if let Some(function_request_data) = self.function_request_data.as_ref() { - if **function_request_data != FunctionRequestAccountData::default() { - return Ok(function_request_data.clone()); - } + // TODO: make this concurrent with a single getMultipleAccounts call + if self.is_routine() { + self.load_routine().await?; } - msg!("fetching request account {}", function_request_key); + // TODO: make this concurrent with a single getMultipleAccounts call + if self.is_request() { + self.load_request().await?; + } - match FunctionRequestAccountData::fetch(&self.client, function_request_key).await { - Ok(function_request_data) => Ok(Box::new(function_request_data)), - Err(error) => Err(SwitchboardClientError::CustomMessage(format!( - "failed to fetch function request {}: {}", - function_request_key, error - ))), + Ok(()) + } + + pub async fn load_function(&mut self) -> Result<(Pubkey, Box), SbError> { + if self.function == Pubkey::default() { + return Err(SbError::Message("Failed to load the function pubkey")); } + + let function_data = self.load_function_data().await?; + self.function_data = Some(function_data.clone()); + + Ok((self.function, function_data)) } /// Builds the callback instruction to send to the Switchboard oracle network. @@ -341,78 +564,117 @@ impl FunctionRunner { &self, mr_enclave: MrEnclave, error_code: u8, - ) -> Result { + ) -> Result { if self.function == Pubkey::default() { - return Err(SwitchboardClientError::CustomMessage( + return Err(SbError::CustomMessage( "funciton pubkey is missing but required to build function_verify ixn".to_string(), )); } - let function_data: FunctionAccountData = *bytemuck::try_from_bytes( - &hex::decode(std::env::var("FUNCTION_DATA").unwrap()).unwrap(), - ) - .unwrap(); + let function_data = self.load_function_data().await?; - let queue_authority = Pubkey::from_str(&std::env::var("QUEUE_AUTHORITY").unwrap()).unwrap(); - let verifier_enclave_signer = - Pubkey::from_str(&std::env::var("VERIFIER_ENCLAVE_SIGNER").unwrap()).unwrap(); + let queue_authority = self + .load_queue_authority(function_data.attestation_queue) + .await?; - let verifier_permission = AttestationPermissionAccountData::get_pda( - &queue_authority, - &function_data.attestation_queue, - &self.verifier, - ); + let verifier_enclave_signer = self.load_verifier_signer(self.verifier).await?; - let maybe_next_allowed_timestamp = function_data.get_next_execution_datetime(); - let next_allowed_timestamp: i64 = if maybe_next_allowed_timestamp.is_some() { - maybe_next_allowed_timestamp.unwrap().timestamp() - } else { - i64::MAX + let next_allowed_timestamp = match function_data.get_next_execution_datetime() { + Some(next_allowed_timestamp) => next_allowed_timestamp.timestamp(), + None => i64::MAX, }; - let ixn_params = FunctionVerifyParams { - observed_time: unix_timestamp(), - next_allowed_timestamp, - error_code, - mr_enclave, - }; + let ixn = FunctionVerify::build_ix( + &FunctionVerifyAccounts { + function: self.function, + function_enclave_signer: self.signer, + function_escrow: function_data.escrow_wallet, + + verifier: self.verifier, + verifier_enclave_signer, + reward_receiver: self.reward_receiver, + + attestation_queue: function_data.attestation_queue, + queue_authority, + }, + &FunctionVerifyParams { + observed_time: unix_timestamp(), + next_allowed_timestamp, + error_code, + mr_enclave, + }, + )?; - let accounts = FunctionVerifyAccounts { - function: self.function, - function_enclave_signer: self.signer, - verifier_quote: self.verifier, - verifier_enclave_signer, - verifier_permission, - escrow_wallet: function_data.escrow_wallet, - escrow_token_wallet: function_data.escrow_token_wallet, - attestation_queue: function_data.attestation_queue, - receiver: self.reward_receiver, - }; - let ixn: Instruction = accounts.get_instruction(ixn_params)?; Ok(ixn) } - /// Builds the callback instruction to send to the Switchboard oracle network. - /// This will execute the instruction to validate the output transaction - /// as well as validate the request parameters used in this run. - async fn build_fn_request_verify_ixn( + ////////////////////////////////////////////////////////////////////////////// + /// Routine Methods + ////////////////////////////////////////////////////////////////////////////// + + /// If this execution is tied to a function routine, load the data of the + /// execution function routine account. + pub async fn load_routine_data(&self) -> Result, SbError> { + let function_routine_key = self.function_routine_key.unwrap_or_default(); + if function_routine_key == Pubkey::default() { + return Err(SbError::CustomMessage( + "function_routine_key is missing but required to fetch function routine account" + .to_string(), + )); + } + + if let Some(function_routine_data) = self.function_routine_data.as_ref() { + if **function_routine_data != FunctionRoutineAccountData::default() { + return Ok(function_routine_data.clone()); + } + } + + msg!( + "FUNCTION_ROUTINE_DATA is missing - Fetching function_routine account {}", + function_routine_key + ); + + match FunctionRoutineAccountData::fetch(&self.client, function_routine_key) { + Ok(function_routine_data) => Ok(Box::new(function_routine_data)), + Err(error) => Err(SbError::CustomMessage(format!( + "failed to fetch function routine {}: {}", + function_routine_key, error + ))), + } + } + + pub async fn load_routine( + &mut self, + ) -> Result<(Pubkey, Box), SbError> { + let routine_pubkey = self.function_routine_key.unwrap_or_default(); + if routine_pubkey == Pubkey::default() { + return Err(SbError::Message("Failed to load the routine pubkey")); + } + + let routine_data = self.load_routine_data().await?; + self.function_routine_data = Some(routine_data.clone()); + + Ok((routine_pubkey, routine_data)) + } + + async fn build_fn_routine_verify_ixn( &self, mr_enclave: MrEnclave, error_code: u8, - ) -> Result { - if self.function_request_data.is_none() || self.function_request_key.is_none() { - return Err(SwitchboardClientError::CustomMessage( - "function_request_verify instruction needs request environment present." + ) -> Result { + if self.function_routine_data.is_none() || self.function_routine_key.is_none() { + return Err(SbError::CustomMessage( + "function_routine_verify instruction needs routine environment present." .to_string(), )); } - let function_request_data = self.function_request_data.clone().unwrap_or_default(); - let function_request_key = self.function_request_key.unwrap_or_default(); + let function_routine_data = self.function_routine_data.clone().unwrap_or_default(); + let function_routine_key = self.function_routine_key.unwrap_or_default(); - if function_request_data.function != self.function { - return Err(SwitchboardClientError::CustomMessage(format!( + if function_routine_data.function != self.function { + return Err(SbError::CustomMessage(format!( "function_key mismatch: expected {}, received {}", - function_request_data.function, self.function + function_routine_data.function, self.function ))); } @@ -423,221 +685,162 @@ impl FunctionRunner { .await?; let verifier_enclave_signer = self.load_verifier_signer(self.verifier).await?; - let verifier_permission = AttestationPermissionAccountData::get_pda( - &queue_authority, - &function_data.attestation_queue, - &self.verifier, - ); - - let container_params_hash = - solana_program::hash::hash(&function_request_data.container_params).to_bytes(); - let ixn_params = FunctionRequestVerifyParams { - observed_time: unix_timestamp(), - error_code, - mr_enclave, - request_slot: function_request_data.active_request.request_slot, - container_params_hash, + let next_allowed_timestamp = match function_data.get_next_execution_datetime() { + Some(next_allowed_timestamp) => next_allowed_timestamp.timestamp(), + None => i64::MAX, }; - let (state_pubkey, _state_bump) = - Pubkey::find_program_address(&[STATE_SEED], &SWITCHBOARD_ATTESTATION_PROGRAM_ID); + let container_params_hash = + solana_program::hash::hash(&function_routine_data.container_params).to_bytes(); - let accounts = FunctionRequestVerifyAccounts { - request: function_request_key, - function_enclave_signer: self.signer, - token_wallet: function_request_data.escrow, - function: self.function, - function_escrow: function_data.escrow_token_wallet, - verifier_quote: self.verifier, - verifier_enclave_signer, - verifier_permission, - state: state_pubkey, - attestation_queue: function_data.attestation_queue, - receiver: self.reward_receiver, + // We only need this pubkey if the function is expected to be rewarded + let function_escrow_token_wallet = if function_data.routines_dev_fee > 0 { + Some(function_data.escrow_token_wallet) + } else { + None }; - let ixn: Instruction = accounts.get_instruction(ixn_params)?; + + let ixn = FunctionRoutineVerify::build_ix( + &FunctionRoutineVerifyAccounts { + routine: function_routine_key, + function_enclave_signer: self.signer, + + escrow_wallet: function_data.escrow_wallet, + + function: self.function, + function_escrow_token_wallet, + + verifier: self.verifier, + verifier_enclave_signer, + reward_receiver: self.reward_receiver, + + attestation_queue: function_data.attestation_queue, + queue_authority, + }, + &FunctionRoutineVerifyParams { + observed_time: unix_timestamp(), + next_allowed_timestamp, + error_code, + mr_enclave, + container_params_hash, + }, + )?; Ok(ixn) } - /// Generates a FunctionResult object to be emitted at the end of this - /// function run. This function result will be used be the quote verification - /// sidecar to verify the output was run inside the function's enclave - /// and sign the transaction to send back on chain. - async fn get_result( - &self, - mut ixs: Vec, - error_code: u8, - ) -> Result { - let quote_raw = Gramine::generate_quote(&self.signer.to_bytes()).unwrap(); - let quote = Quote::parse("e_raw).unwrap(); - let mr_enclave: MrEnclave = quote.isv_report.mrenclave.try_into().unwrap(); + ////////////////////////////////////////////////////////////////////////////// + /// Request Methods + ////////////////////////////////////////////////////////////////////////////// + /// If this execution is tied to a function request, load the data of the + /// execution function request account. + pub async fn load_request_data(&self) -> Result, SbError> { let function_request_key = self.function_request_key.unwrap_or_default(); - let verify_ixn = if function_request_key == Pubkey::default() { - self.build_fn_verify_ixn(mr_enclave, error_code).await? - } else { - self.build_fn_request_verify_ixn(mr_enclave, error_code) - .await? - }; - ixs.insert(0, verify_ixn); - let message = Message::new(&ixs, Some(&self.payer)); - let blockhash = self.client.get_latest_blockhash().unwrap(); - let mut tx = solana_sdk::transaction::Transaction::new_unsigned(message); - tx.partial_sign(&[self.signer_keypair.as_ref()], blockhash); + if function_request_key == Pubkey::default() { + return Err(SbError::CustomMessage( + "function_request_key is missing but required to fetch function request account" + .to_string(), + )); + } - let fn_request_key: Vec = if function_request_key != Pubkey::default() { - function_request_key.to_bytes().to_vec() - } else { - vec![] - }; + if let Some(function_request_data) = self.function_request_data.as_ref() { + if **function_request_data != FunctionRequestAccountData::default() { + return Ok(function_request_data.clone()); + } + } - Ok(FunctionResult { - version: 1, - quote: quote_raw, - fn_key: self.function.to_bytes().into(), - signer: self.signer.to_bytes().into(), - fn_request_key, - // TODO: hash should be checked against - fn_request_hash: Vec::new(), - chain_result_info: Solana(SOLFunctionResult { - serialized_tx: bincode::serialize(&tx).unwrap(), - }), - error_code, - }) + msg!( + "FUNCTION_REQUEST_DATA is missing - Fetching function_request account {}", + function_request_key + ); + + match FunctionRequestAccountData::fetch(&self.client, function_request_key) { + Ok(function_request_data) => Ok(Box::new(function_request_data)), + Err(error) => Err(SbError::CustomMessage(format!( + "failed to fetch function request {}: {}", + function_request_key, error + ))), + } } - /// Emits a serialized FunctionResult object to send to the quote verification - /// sidecar. - pub async fn emit(&self, ixs: Vec) -> Result<(), SwitchboardClientError> { - self.get_result(ixs, 0) - .await - .map_err(|e| { - SwitchboardClientError::CustomMessage(format!("failed to get verify ixn: {}", e)) - }) - .unwrap() - .emit(); + pub async fn load_request( + &mut self, + ) -> Result<(Pubkey, Box), SbError> { + let request_pubkey = self.function_request_key.unwrap_or_default(); + if request_pubkey == Pubkey::default() { + return Err(SbError::Message("Failed to load the request pubkey")); + } - Ok(()) - } + let request_data = self.load_request_data().await?; + self.function_request_data = Some(request_data.clone()); - pub async fn emit_error(&self, error_code: u8) -> Result<(), SwitchboardClientError> { - self.get_result(vec![], error_code).await.unwrap().emit(); - Ok(()) + Ok((request_pubkey, request_data)) } -} -// Useful for building ixns on the client side -/// Implements the instruction schema for serialization the -/// function_verify instruction -pub struct FunctionVerifyAccounts { - pub function: Pubkey, - pub function_enclave_signer: Pubkey, - pub verifier_quote: Pubkey, - pub verifier_enclave_signer: Pubkey, - pub verifier_permission: Pubkey, - pub escrow_wallet: Pubkey, - pub escrow_token_wallet: Pubkey, - pub receiver: Pubkey, - pub attestation_queue: Pubkey, -} -impl FunctionVerifyAccounts { - /// Generates an instruction to verify the provided function call - pub fn get_instruction( + /// Builds the callback instruction to send to the Switchboard oracle network. + /// This will execute the instruction to validate the output transaction + /// as well as validate the request parameters used in this run. + async fn build_fn_request_verify_ixn( &self, - params: FunctionVerifyParams, - ) -> std::result::Result { - let accounts = self.to_account_metas(None); - let mut data: Vec = FunctionVerify::discriminator().try_to_vec().map_err(|_| { - SwitchboardClientError::CustomMessage( - "failed to get function_verify discriminator".to_string(), - ) - })?; - let mut param_vec: Vec = params.try_to_vec().map_err(|_| { - SwitchboardClientError::CustomMessage( - "failed to serialize function_verify ixn data".to_string(), - ) - })?; - data.append(&mut param_vec); + mr_enclave: MrEnclave, + error_code: u8, + ) -> Result { + if self.function_request_data.is_none() || self.function_request_key.is_none() { + return Err(SbError::CustomMessage( + "function_request_verify instruction needs request environment present." + .to_string(), + )); + } + let function_request_data = self.function_request_data.clone().unwrap_or_default(); + let function_request_key = self.function_request_key.unwrap_or_default(); - let instruction = - Instruction::new_with_bytes(SWITCHBOARD_ATTESTATION_PROGRAM_ID, &data, accounts); - Ok(instruction) - } -} + if function_request_data.function != self.function { + return Err(SbError::CustomMessage(format!( + "function_key mismatch: expected {}, received {}", + function_request_data.function, self.function + ))); + } -impl ToAccountMetas for FunctionVerifyAccounts { - fn to_account_metas(&self, _: Option) -> Vec { - vec![ - AccountMeta::new(self.function, false), - AccountMeta::new_readonly(self.function_enclave_signer, true), - AccountMeta::new_readonly(self.verifier_quote, false), - AccountMeta::new_readonly(self.verifier_enclave_signer, true), - AccountMeta::new_readonly(self.verifier_permission, false), - AccountMeta::new_readonly(self.escrow_wallet, false), - AccountMeta::new(self.escrow_token_wallet, false), - AccountMeta::new(self.receiver, false), - AccountMeta::new_readonly(self.attestation_queue, false), - AccountMeta::new_readonly(anchor_spl::token::ID, false), - ] - } -} -/// Implements the instruction schema for serialization the -/// function_request_verify instruction -pub struct FunctionRequestVerifyAccounts { - pub request: Pubkey, - pub function_enclave_signer: Pubkey, - pub token_wallet: Pubkey, - pub function: Pubkey, - pub function_escrow: Pubkey, - pub verifier_quote: Pubkey, - pub verifier_enclave_signer: Pubkey, - pub verifier_permission: Pubkey, - pub receiver: Pubkey, - pub state: Pubkey, - pub attestation_queue: Pubkey, -} -impl FunctionRequestVerifyAccounts { - /// Generates an instruction to verify the provided request call - pub fn get_instruction( - &self, - params: FunctionRequestVerifyParams, - ) -> std::result::Result { - let accounts = self.to_account_metas(None); - let mut data: Vec = FunctionRequestVerify::discriminator() - .try_to_vec() - .map_err(|_| { - SwitchboardClientError::CustomMessage( - "failed to get function_request_verify discriminator".to_string(), - ) - })?; - let mut param_vec: Vec = params.try_to_vec().map_err(|_| { - SwitchboardClientError::CustomMessage( - "failed to serialize function_request_verify ixn data".to_string(), - ) - })?; - data.append(&mut param_vec); + let function_data = self.load_function_data().await?; - let instruction = - Instruction::new_with_bytes(SWITCHBOARD_ATTESTATION_PROGRAM_ID, &data, accounts); - Ok(instruction) - } -} + let queue_authority = self + .load_queue_authority(function_data.attestation_queue) + .await?; + let verifier_enclave_signer = self.load_verifier_signer(self.verifier).await?; + + let container_params_hash = + solana_program::hash::hash(&function_request_data.container_params).to_bytes(); -impl ToAccountMetas for FunctionRequestVerifyAccounts { - fn to_account_metas(&self, _: Option) -> Vec { - vec![ - AccountMeta::new(self.request, false), - AccountMeta::new_readonly(self.function_enclave_signer, true), - AccountMeta::new(self.token_wallet, false), - AccountMeta::new(self.function, false), - AccountMeta::new(self.function_escrow, false), - AccountMeta::new_readonly(self.verifier_quote, false), - AccountMeta::new_readonly(self.verifier_enclave_signer, true), - AccountMeta::new_readonly(self.verifier_permission, false), - AccountMeta::new_readonly(self.state, false), - AccountMeta::new_readonly(self.attestation_queue, false), - AccountMeta::new(self.receiver, false), - AccountMeta::new_readonly(anchor_spl::token::ID, false), - ] + // We only need this pubkey if the function is expected to be rewarded + let function_escrow_token_wallet = if function_data.routines_dev_fee > 0 { + Some(function_data.escrow_token_wallet) + } else { + None + }; + + let ixn = FunctionRequestVerify::build_ix( + &FunctionRequestVerifyAccounts { + request: function_request_key, + function_enclave_signer: self.signer, + + function: self.function, + function_escrow_token_wallet, + + verifier: self.verifier, + verifier_enclave_signer, + reward_receiver: self.reward_receiver, + + attestation_queue: function_data.attestation_queue, + queue_authority, + }, + &FunctionRequestVerifyParams { + observed_time: unix_timestamp(), + error_code, + mr_enclave, + request_slot: function_request_data.active_request.request_slot, + container_params_hash, + }, + )?; + Ok(ixn) } } diff --git a/rust/switchboard-solana/src/client/mod.rs b/rust/switchboard-solana/src/client/mod.rs index 46d732554..2d7dc3891 100644 --- a/rust/switchboard-solana/src/client/mod.rs +++ b/rust/switchboard-solana/src/client/mod.rs @@ -1,7 +1,13 @@ -pub mod function_runner; +mod function_runner; pub use function_runner::*; -pub mod utils; +mod program; +pub use program::get_attestation_program; + +mod utils; pub use utils::*; +mod validator; +pub use validator::*; + pub use switchboard_common::SolanaFunctionEnvironment; diff --git a/rust/switchboard-solana/src/client/program.anchor27.rs b/rust/switchboard-solana/src/client/program.anchor27.rs new file mode 100644 index 000000000..6c6b57fe1 --- /dev/null +++ b/rust/switchboard-solana/src/client/program.anchor27.rs @@ -0,0 +1,12 @@ +use anchor_client::solana_sdk::signature::Keypair; +use anchor_client::{ Program, Client }; +use switchboard_common::SbError; +use std::sync::Arc; +use std::result::Result; +use crate::SWITCHBOARD_ATTESTATION_PROGRAM_ID; + +pub fn get_attestation_program( + client: &Client> +) -> Result>, SbError> { + Ok(client.program(SWITCHBOARD_ATTESTATION_PROGRAM_ID)) +} diff --git a/rust/switchboard-solana/src/client/program.rs b/rust/switchboard-solana/src/client/program.rs new file mode 100644 index 000000000..c35a966a2 --- /dev/null +++ b/rust/switchboard-solana/src/client/program.rs @@ -0,0 +1,15 @@ +use anchor_client::solana_sdk::signature::Keypair; +use anchor_client::{ Program, Client }; +use switchboard_common::SbError; +use std::sync::Arc; +use std::result::Result; +use crate::SWITCHBOARD_ATTESTATION_PROGRAM_ID; + +pub fn get_attestation_program( + client: &Client> +) -> Result>, SbError> { + client.program(SWITCHBOARD_ATTESTATION_PROGRAM_ID).map_err(|e| SbError::CustomError { + message: "Failed to get Anchor program".to_string(), + source: Arc::new(e), + }) +} diff --git a/rust/switchboard-solana/src/client/utils.rs b/rust/switchboard-solana/src/client/utils.rs index 5c24e3331..5942b07f3 100644 --- a/rust/switchboard-solana/src/client/utils.rs +++ b/rust/switchboard-solana/src/client/utils.rs @@ -1,15 +1,130 @@ use crate::prelude::*; -use solana_sdk::signer::keypair::{keypair_from_seed, Keypair}; + +use anchor_client::anchor_lang::Event; +use anchor_client::solana_sdk::commitment_config::CommitmentConfig; +use sha2::{ Digest, Sha256 }; +use solana_client::nonblocking::rpc_client::RpcClient as NonblockingRpcClient; +use solana_sdk::client::SyncClient; +use solana_sdk::signer::keypair::{ keypair_from_seed, read_keypair_file, Keypair }; use solana_sdk::signer::Signer; use std::env; use std::result::Result; use std::str::FromStr; use std::sync::Arc; -use std::time::{SystemTime, UNIX_EPOCH}; +use tokio::sync::RwLock; +use base64::{ engine::general_purpose, Engine as _ }; +use solana_client::rpc_config::RpcTransactionLogsFilter; +use solana_client::nonblocking::pubsub_client::PubsubClient; +use solana_client::rpc_config::RpcTransactionLogsConfig; +use futures::{ Future, StreamExt }; +use super::program::get_attestation_program; + +pub fn build_tx( + anchor_client: &anchor_client::Client>, + program_id: &Pubkey, + accounts: A, + params: I, + signers: Vec<&Keypair> +) -> Result { + let payer = signers[0]; + let ix = Instruction { + program_id: *program_id, + accounts: accounts.to_account_metas(None), + data: params.data(), + }; + let mut tx = Transaction::new_with_payer(&[ix], Some(&payer.pubkey())); + let program = get_attestation_program(anchor_client)?; + let blockhash = program.rpc().get_latest_blockhash().unwrap_or_default(); + tx.try_sign(&signers, blockhash).map_err(|e| SbError::CustomError { + message: "Failed to sign txn".into(), + source: std::sync::Arc::new(e), + })?; + Ok(tx) +} + +pub async fn get_async_rpc( + client: &Arc> +) -> Result, SbError> { + let client = client.clone(); + let ro_client = client.read().await; + let program = get_attestation_program(&ro_client)?; + let rpc = program.async_rpc(); + Ok(Arc::new(rpc)) +} + +pub fn ix_to_tx( + ixs: &[Instruction], + signers: &[&Keypair], + blockhash: solana_program::hash::Hash +) -> Result { + let msg = Message::new(ixs, Some(&signers[0].pubkey())); + let mut tx = Transaction::new_unsigned(msg); + // for (i,s) in signers.iter().enumerate() { + // tx.try_sign(&signers.to_vec(), blockhash) + // .map_err(|e| SbError::CustomError { message: format!("Failed to sign txn", {}), source: std::sync::Arc::new(e) })?; + // } + tx.try_sign(&signers.to_vec(), blockhash).map_err(|e| SbError::CustomError { + message: "Failed to sign txn".into(), + source: std::sync::Arc::new(e), + })?; + Ok(tx) +} + +pub async fn get_enclave_signer_pubkey( + enclave_signer: &Arc> +) -> Result, SbError> { + let enclave_signer = enclave_signer.clone(); + let ro_enclave_signer = enclave_signer.read().await; + let pubkey = Arc::new(ro_enclave_signer.pubkey()); + Ok(pubkey) +} + +pub fn load_env_pubkey(key: &str) -> Result { + Pubkey::from_str(&env::var(key).unwrap_or_default()).map_err(|_| + SbError::EnvVariableMissing(key.to_string()) + ) +} + +/// Parse a string into an optional Pubkey. If the string is empty, return None. +pub fn parse_optional_pubkey(var: &str) -> Option { + if var.is_empty() { + None + } else { + match Pubkey::from_str(var) { + Ok(pubkey) => { + if pubkey != Pubkey::default() { Some(pubkey) } else { None } + } + Err(_) => None, + } + } +} + +pub fn keypair_from_base_seed( + base: &str, + secret_key: Vec, + more_bytes: Option> +) -> Result, SbError> { + if secret_key.len() != 32 { + return Err(SbError::Message("InvalidSecretKey")); + } + + let mut seed = base.as_bytes().to_vec(); + seed.extend_from_slice(&secret_key); + + if let Some(bytes) = more_bytes.as_ref() { + seed.extend_from_slice(bytes); + } -pub fn load_env_pubkey(key: &str) -> Result { - Pubkey::from_str(&env::var(key).unwrap_or_default()) - .map_err(|_| SwitchboardClientError::EnvVariableMissing(key.to_string())) + match keypair_from_seed(&Sha256::digest(&seed)) { + Ok(keypair) => Ok(Arc::new(keypair)), + Err(e) => { + if let Some(err) = e.source() { + println!("Failed to derive keypair -- {}", err); + } + + Err(SbError::Message("Failed to derive keypair")) + } + } } /// Creates a signing keypair generated from randomness sourced from the enclave @@ -20,59 +135,188 @@ pub fn generate_signer() -> Arc { Arc::new(keypair_from_seed(&randomness).unwrap()) } -pub fn signer_to_pubkey( - signer: Arc, -) -> std::result::Result { +pub fn signer_to_pubkey(signer: Arc) -> std::result::Result { Ok(signer.pubkey()) } -pub async fn load_account( +pub fn load_keypair_fs(fs_path: &str) -> Result, SbError> { + match read_keypair_file(fs_path) { + Ok(keypair) => Ok(Arc::new(keypair)), + Err(e) => { + if let Some(err) = e.source() { + println!("Failed to read keypair file -- {}", err); + } + + Err(SbError::Message("Failed to read keypair file")) + } + } +} + +pub fn fetch_zerocopy_account( client: &solana_client::rpc_client::RpcClient, - pubkey: Pubkey, -) -> Result { + pubkey: Pubkey +) -> Result { + let data = client.get_account_data(&pubkey).map_err(|_| SbError::AccountNotFound)?; + + if data.len() < T::discriminator().len() { + return Err(SbError::Message("no discriminator found")); + } + + let mut disc_bytes = [0u8; 8]; + disc_bytes.copy_from_slice(&data[..8]); + if disc_bytes != T::discriminator() { + return Err(SbError::Message("Discriminator error, check the account type")); + } + + Ok( + *bytemuck + ::try_from_bytes::(&data[8..]) + .map_err(|_| SbError::Message("AnchorParseError"))? + ) +} + +pub fn fetch_zerocopy_account_sync( + client: &C, + pubkey: Pubkey +) -> Result { let data = client .get_account_data(&pubkey) - .map_err(|_| SwitchboardClientError::CustomMessage("AnchorParseError".to_string()))?; + .map_err(|_| SbError::AccountNotFound)? + .ok_or(SbError::AccountNotFound)?; if data.len() < T::discriminator().len() { - return Err(SwitchboardClientError::CustomMessage( - "no discriminator found".to_string(), - )); + return Err(SbError::Message("no discriminator found")); } let mut disc_bytes = [0u8; 8]; disc_bytes.copy_from_slice(&data[..8]); if disc_bytes != T::discriminator() { - return Err(SwitchboardClientError::CustomMessage( - "Discriminator error, check the account type".to_string(), - )); + return Err(SbError::Message("Discriminator error, check the account type")); } - Ok(*bytemuck::try_from_bytes::(&data[8..]) - .map_err(|_| SwitchboardClientError::CustomMessage("AnchorParseError".to_string()))?) + Ok( + *bytemuck + ::try_from_bytes::(&data[8..]) + .map_err(|_| SbError::Message("AnchorParseError"))? + ) } -pub async fn fetch_anchor_account( +pub async fn fetch_zerocopy_account_async( + client: &NonblockingRpcClient, + pubkey: Pubkey +) -> Result { + let data = client.get_account_data(&pubkey).await.map_err(|e| SbError::CustomError { + message: "Failed to get account data".to_string(), + source: Arc::new(e), + })?; + + if data.len() < T::discriminator().len() { + return Err(SbError::Message("no discriminator found")); + } + + let mut disc_bytes = [0u8; 8]; + disc_bytes.copy_from_slice(&data[..8]); + if disc_bytes != T::discriminator() { + return Err(SbError::Message("Discriminator error, check the account type")); + } + + Ok( + *bytemuck + ::try_from_bytes::(&data[8..]) + .map_err(|_| SbError::Message("AnchorParseError"))? + ) +} + +pub fn fetch_borsh_account( client: &solana_client::rpc_client::RpcClient, - pubkey: Pubkey, -) -> Result { - T::try_deserialize( - &mut client - .get_account_data(&pubkey) - .map_err(|e| SwitchboardClientError::CustomError { - message: "SolanaFetchError".to_string(), - source: std::sync::Arc::new(e), - })? - .as_slice(), + pubkey: Pubkey +) -> Result { + let account_data = client.get_account_data(&pubkey).map_err(|_| SbError::AccountNotFound)?; + + T::try_deserialize(&mut account_data.as_slice()).map_err(|_| + SbError::Message("AnchorParseError") + ) +} + +pub async fn fetch_borsh_account_async( + client: &NonblockingRpcClient, + pubkey: Pubkey +) -> Result { + let account_data = client + .get_account_data(&pubkey).await + .map_err(|_| SbError::AccountNotFound)?; + + T::try_deserialize(&mut account_data.as_slice()).map_err(|_| + SbError::Message("AnchorParseError") ) - .map_err(|_| SwitchboardClientError::CustomMessage("AnchorParseError".to_string())) } -pub fn unix_timestamp() -> i64 { - SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap_or_default() - .as_secs() - .try_into() - .unwrap_or(0) +pub fn fetch_borsh_account_sync( + client: &C, + pubkey: Pubkey +) -> Result { + let data = client + .get_account_data(&pubkey) + .map_err(|_| SbError::AccountNotFound)? + .ok_or(SbError::AccountNotFound)?; + + T::try_deserialize(&mut data.as_slice()).map_err(|_| SbError::Message("AnchorParseError")) +} + +pub async fn subscribe( + program_id: Pubkey, + url: &str, + client: Arc>, + quote_key: Arc, + enclave_key: Arc>, + payer: Arc, + async_fn: F +) + where + F: Fn(Arc>, Arc, Arc>, Arc, E) -> T + + Send + + Sync + + 'static, + T: Future + Send + 'static, + E: Event +{ + // TODO: This may pull events from other programs if targeted but the + // request still goes through verification so not a fatal issue. + let pubsub_client = PubsubClient::new(url).await.unwrap(); + loop { + let (mut r, _handler) = pubsub_client + .logs_subscribe( + RpcTransactionLogsFilter::Mentions(vec![program_id.to_string()]), + RpcTransactionLogsConfig { + commitment: Some(CommitmentConfig::processed()), + } + ).await + .unwrap(); + while let Some(event) = r.next().await { + let log: String = event.value.logs.join(" "); + for w in log.split(' ') { + let decoded = general_purpose::STANDARD.decode(w); + if decoded.is_err() { + continue; + } + let decoded = decoded.unwrap(); + if decoded.len() < 8 { + continue; + } + if decoded[..8] != E::DISCRIMINATOR { + continue; + } + + if let Ok(event) = E::try_from_slice(&decoded[8..]) { + async_fn( + client.clone(), + quote_key.clone(), + enclave_key.clone(), + payer.clone(), + event + ).await; + } + } + } + } } diff --git a/rust/switchboard-solana/src/client/validator.rs b/rust/switchboard-solana/src/client/validator.rs new file mode 100644 index 000000000..795c761a9 --- /dev/null +++ b/rust/switchboard-solana/src/client/validator.rs @@ -0,0 +1,1481 @@ +use crate::*; + +use anchor_client::solana_sdk::commitment_config::CommitmentConfig; +use solana_client::rpc_config::RpcSimulateTransactionConfig; +use anchor_client::solana_sdk::transaction::{ Transaction, TransactionError }; +use anchor_lang::Discriminator; +use dashmap::DashMap; +use sha2::{ Digest, Sha256 }; +use solana_client::nonblocking::rpc_client::RpcClient; +use solana_sdk::signature::Signature; +use solana_sdk::signer::keypair::Keypair; +use solana_sdk::signer::Signer; +use std::sync::Arc; +use tokio::sync::RwLock; + +pub type AnchorClient = anchor_client::Client>; +pub type AnchorProgram = anchor_client::Program>; + +pub type QuoteVerifyFn = dyn (Fn(&[u8], i64) -> bool) + Send + Sync; + +#[derive(Default, Clone)] +pub struct CacheEntry { + pub pubkey: Pubkey, + pub timestamp: i64, +} + +#[derive(Clone, serde::Serialize, serde::Deserialize)] +pub enum QvnReceipt { + /// QVN completed successfully with a exit status of 0 + Success(String), // signature + /// QVN completed successfully with an error code [200-255] + SwitchboardError(String, u8), // signature, error code + /// QVN failed to verify user transaction and fellback to a default transaction + Fallback(String, u8), // signature, error code +} + +#[derive(Clone)] +pub struct FunctionResultValidatorCache { + pub timeout: Option, + pub function_escrow_wallet: Arc>, + pub routine_escrow_wallet: Arc>, +} +impl Default for FunctionResultValidatorCache { + fn default() -> Self { + Self { + timeout: Some(300), + function_escrow_wallet: Arc::new(DashMap::with_capacity(10_000)), + routine_escrow_wallet: Arc::new(DashMap::with_capacity(10_000)), + } + } +} + +/// The list of accounts used by this verifier to verify the function result +#[derive(Default, Debug, Clone)] +pub struct FunctionResultValidatorAccounts { + pub payer: Pubkey, + + pub verifier: Pubkey, + pub verifier_enclave_signer: Pubkey, + pub reward_receiver: Pubkey, + + pub attestation_queue: Pubkey, + pub queue_authority: Pubkey, +} + +/// The cleaned up parameters used for a verify instruction +#[derive(Default, Debug, Clone)] +pub struct FunctionValidatorVerifyParams { + pub mr_enclave: [u8; 32], + pub error_code: u8, + pub observed_time: i64, + pub container_params_hash: [u8; 32], + // optional + pub request_slot: u64, + pub next_allowed_timestamp: i64, +} + +/// Represents a [`VerifierAccountData`] oracle and verifies an emitted FunctionResult +#[derive(Clone)] +pub struct FunctionResultValidator { + pub client: Arc>, + pub rpc: Arc, + pub payer: Arc, + + // verifier fields + pub verifier: Arc, + pub verifier_enclave_signer: FunctionResultValidatorSigner, + pub reward_receiver: Arc, + + // queue fields + pub attestation_queue: Arc, + pub queue_authority: Arc, + + pub quote_verify_fn: Arc>, + + // cache some of the escrow pubkeys for faster execution + pub cache: FunctionResultValidatorCache, +} + +pub struct FunctionResultValidatorInitAccounts { + pub verifier: Pubkey, + pub attestation_queue: Pubkey, + pub queue_authority: Pubkey, + pub reward_receiver: Pubkey, +} + +#[derive(Debug, Clone)] +pub enum FunctionResultValidatorSigner { + Simulation(Arc), + Production(Arc>), +} + +impl FunctionResultValidator { + /// Create a new instance of the [`FunctionResultValidator`] + pub fn new( + client: Arc>, + rpc: Arc, + payer: Arc, + verifier_enclave_signer: FunctionResultValidatorSigner, + accounts: &FunctionResultValidatorInitAccounts, + quote_verify_fn: impl (Fn(&[u8], i64) -> bool) + 'static + Send + Sync, + cache: Option + ) -> Self { + Self { + client: client.clone(), + rpc: rpc.clone(), + payer: payer.clone(), + + verifier: Arc::new(accounts.verifier), + // verifier_enclave_keypair, + verifier_enclave_signer, + reward_receiver: Arc::new(accounts.reward_receiver), + + attestation_queue: Arc::new(accounts.attestation_queue), + queue_authority: Arc::new(accounts.queue_authority), + + quote_verify_fn: Arc::new(Box::new(quote_verify_fn)), + + cache: cache.unwrap_or_default(), + } + } + + pub async fn load( + client: Arc>, + payer: Arc, + verifier: Pubkey, + verifier_enclave_signer: Option, + reward_receiver: Option, + quote_verify_fn: impl (Fn(&[u8], i64) -> bool) + 'static + Send + Sync, + cache: Option + ) -> Result { + let rpc = get_async_rpc(&client).await?; + + let verifier_data = VerifierAccountData::fetch_async(rpc.as_ref(), verifier).await?; + + let verifier_enclave_signer = match verifier_enclave_signer { + Some(verifier_enclave_signer) => { + match &verifier_enclave_signer { + FunctionResultValidatorSigner::Simulation(pubkey) => { + if **pubkey != verifier_data.enclave.enclave_signer { + return Err( + SbError::Message( + "The provided verifier signer does not match the expected signer's pubkey" + ) + ); + } + } + FunctionResultValidatorSigner::Production(keypair) => { + let signer_pubkey = get_enclave_signer_pubkey(keypair).await?; + if *signer_pubkey != verifier_data.enclave.enclave_signer { + return Err( + SbError::Message( + "The provided verifier signer does not match the expected signer's pubkey" + ) + ); + } + } + } + verifier_enclave_signer + } + None => + FunctionResultValidatorSigner::Simulation( + Arc::new(verifier_data.enclave.enclave_signer) + ), + }; + + let attestation_queue = AttestationQueueAccountData::fetch_async( + &rpc, + verifier_data.attestation_queue + ).await?; + + Ok( + FunctionResultValidator::new( + client, + rpc.clone(), + payer, + verifier_enclave_signer, + &(FunctionResultValidatorInitAccounts { + verifier, + attestation_queue: verifier_data.attestation_queue, + queue_authority: attestation_queue.authority, + reward_receiver: reward_receiver.unwrap_or_default(), + }), + quote_verify_fn, + cache + ) + ) + } + + pub async fn load_from_cluster( + cluster: Cluster, + payer: Arc, + verifier: Pubkey, + verifier_enclave_signer: Option, + reward_receiver: Option, + quote_verify_fn: impl (Fn(&[u8], i64) -> bool) + 'static + Send + Sync, + cache: Option + ) -> Result { + let client = AnchorClient::new_with_options( + cluster, + payer.clone(), + CommitmentConfig::processed() + ); + + Self::load( + Arc::new(RwLock::new(client)), + payer, + verifier, + verifier_enclave_signer, + reward_receiver, + quote_verify_fn, + cache + ).await + } + + /// Whether the validator is in production mode and is ready to sign and send transactions. + pub fn is_production(&self) -> bool { + matches!(&self.verifier_enclave_signer, FunctionResultValidatorSigner::Production(_)) + } + + /// Whether the validator is in simulation mode and is ready to validate function requests. + pub fn is_simulation(&self) -> bool { + matches!(&self.verifier_enclave_signer, FunctionResultValidatorSigner::Simulation(_)) + } + + /// Check if the verifier_enclave_keypair is present so we can sign and send transactions. + async fn get_verifier_enclave_signer(&self) -> Result, SbError> { + match &self.verifier_enclave_signer { + FunctionResultValidatorSigner::Production(keypair) => { + // Kind of ugly but we re-create the keypair so we dont need to always await the lock + let kp = keypair.read().await; + let kp2 = Keypair::from_bytes(&kp.to_bytes()).unwrap(); + Ok(Arc::new(kp2)) + } + _ => + Err( + SbError::Message( + "FunctionResultValidator is in simulation mode - please provide the verifier_enclave_keypair in order to process and send any transactions on behalf of the verifier oracle" + ) + ), + } + } + + async fn get_verifier_enclave_pubkey(&self) -> Arc { + match &self.verifier_enclave_signer { + FunctionResultValidatorSigner::Simulation(pubkey) => pubkey.clone(), + FunctionResultValidatorSigner::Production(keypair) => { + Arc::new(keypair.read().await.pubkey()) + } + } + } + + /// The entrypoint for the QVN. Verifies a FunctionResult and returns a transaction signature if successful. + pub async fn process(&self, function_result: &FunctionResult) -> Result { + let (signature, _error_code) = match self.validate(function_result).await { + Ok(mut tx) => { + // Send transaction + // By this point it should have passed simulation and signature verification + (self.send_txn(&mut tx).await.unwrap(), None) + } + Err(err) => { + let function_pubkey = Pubkey::try_from_slice( + function_result.fn_key().unwrap_or_default().as_slice() + ).unwrap_or_default(); + // Try to catch error and send transaction + + let error_code = match err { + SbError::FunctionResultFailoverError(error_code, e) => { + println!( + "[QVN]({}) Failed to send transaction, sending fallback txn with error code ({}).\n{:?}", + function_pubkey, + error_code, + e + ); + Some(error_code) + } + SbError::FunctionResultNonRetryableError(e) => { + println!("[QVN]({}) Failed with non-retryable error.\n{:?}", function_pubkey, e); + None + } + _ => { + println!("[QVN]({}) No error handler found for error {:?}", function_pubkey, err); + Some(211) // improve this + } + }; + + if let Some(error_code) = error_code { + let mut tx = self + .produce_failover_tx(function_result, Some(error_code)).await + .unwrap(); + (self.send_txn(&mut tx).await.unwrap(), Some(error_code)) + } else { + (Signature::default(), None) + } + } + }; + + Ok(signature) + } + + /// Validate the function result and return any errors + pub async fn validate(&self, function_result: &FunctionResult) -> Result { + let error_code = function_result.error_code(); + // if error_code < 200 { + // println!("[QVN] Function Result\n{:?}", function_result); + // } + + // 1. Validate the [`FunctionResult`] is for the Solana chain + let solana_function_result = if + let Ok(switchboard_common::ChainResultInfo::Solana(chain_result_info)) = + function_result.chain_result_info() + { + chain_result_info + } else { + return Err(SbError::InvalidChain); + }; + + let function_pubkey = Pubkey::try_from_slice( + function_result.fn_key().unwrap().as_slice() + ).unwrap(); + let function_enclave_signer = Pubkey::try_from_slice(function_result.signer()).unwrap(); + + // If the error_code is 200 or greater, we can skip the quote verification and just rebuild the tx ourselves + if error_code >= 200 { + return Ok(self.produce_failover_tx(function_result, Some(error_code)).await.unwrap()); + } + + // 2. Build and verify the transaction + let (tx, request_type, untrusted_verify_idx) = self.build_and_verify_txn( + &solana_function_result + ).await?; + let untrusted_verify_ix = &tx.message.instructions[untrusted_verify_idx as usize]; + let verify_param_bytes = untrusted_verify_ix.data[8..].to_vec(); + let untrusted_params = FunctionResultValidator::get_params( + &request_type, + verify_param_bytes.clone() + )?; + + // 3. Parse the quote + let quote_bytes = function_result.quote_bytes(); + let quote = sgx_quote::Quote::parse("e_bytes).map_err(|_| SbError::QuoteParseError)?; + + // 4. Verify the MrEnclave matches the quote + if untrusted_params.mr_enclave != quote.isv_report.mrenclave { + println!("[QVN] {:?}: mr_enclave mismatch", function_pubkey); + // Should we exit here or let it continue and handle the error on-chain? + return Err(SbError::MrEnclaveMismatch); + } + + // 6. Verify the SGX quote + // 6a. Verify the report keyhash matches the enclave generated signer + let report_keyhash = "e.isv_report.report_data[..32]; + if report_keyhash != Sha256::digest(function_enclave_signer.to_bytes()).as_slice() { + println!( + "[QVN] [{:?}]: keyhash mismatch: {:?} vs {:?}", + function_pubkey, + report_keyhash, + Sha256::digest(function_enclave_signer.to_bytes()).as_slice() + ); + + return Err( + SbError::FunctionResultFailoverError( + 200, + Arc::new(SbError::FunctionResultIxError("IllegalEnclaveSigner")) + ) + ); + } + + // 6b. Verify the SGX quote cryptography + if !(self.quote_verify_fn)(quote_bytes, untrusted_params.observed_time) { + return Err( + SbError::FunctionResultFailoverError( + 201, + Arc::new(SbError::FunctionResultError("InvalidQuote")) + ) + ); + } + + // early exit if the error code is greater than 0, quote is empty, and enclave_signer is null + + // 5. Build trusted verify ixn and compare with untrusted_verify_ixn + let trusted_ix = self.build_trusted_verify_ixn( + &function_pubkey, + &function_enclave_signer, + &request_type, + &untrusted_params + ).await?; + if trusted_ix.data != untrusted_verify_ix.data { + println!("[QVN] Left-data: {:?}", trusted_ix.data); + println!("[QVN] Right-data: {:?}", untrusted_verify_ix.data); + return Err( + SbError::FunctionResultFailoverError( + 200, + Arc::new(SbError::FunctionResultIxError("IllegalVerifyInstructionData")) + ) + ); + } + let mut untrusted_accounts = vec![]; + for account_idx in &untrusted_verify_ix.accounts { + if (*account_idx as usize) >= tx.message.account_keys.len() { + return Err(SbError::FunctionResultIxError("AccountsMismatch")); + } + untrusted_accounts.push(tx.message.account_keys[*account_idx as usize]); + } + let trusted_accounts: Vec = trusted_ix.accounts + .iter() + .map(|x| x.pubkey) + .collect(); + + // Some verify accounts can be optional where the pubkey is set to the attestation program ID. So we + // need to account for that. + // TODO: add test case for this + if trusted_accounts.len() != untrusted_accounts.len() { + println!("[QVN] {}: LEFT: {:#?}", function_pubkey, trusted_accounts); + println!("[QVN] {}: RIGHT: {:#?}", function_pubkey, untrusted_accounts); + return Err( + SbError::FunctionResultFailoverError( + 200, + Arc::new(SbError::FunctionResultIxError("IllegalVerifyAccounts")) + ) + ); + } + for (i, trusted_account) in trusted_accounts.iter().enumerate() { + let untrusted_account = untrusted_accounts.get(i).unwrap(); + if + untrusted_account != trusted_account && + untrusted_account != &SWITCHBOARD_ATTESTATION_PROGRAM_ID + { + println!("[QVN] {}: LEFT: {:#?}", function_pubkey, trusted_accounts); + println!("[QVN] {}: RIGHT: {:#?}", function_pubkey, untrusted_accounts); + return Err( + SbError::FunctionResultFailoverError( + 200, + Arc::new(SbError::FunctionResultIxError("IllegalVerifyAccounts")) + ) + ); + } + } + + // 7. Simulate the transaction and build any fail over logic + // TODO: should we do this in production? Probably not + let replace_blockhash = tx.message.recent_blockhash == Default::default(); + match + self.rpc.simulate_transaction_with_config(&tx, RpcSimulateTransactionConfig { + sig_verify: false, + replace_recent_blockhash: replace_blockhash, + commitment: Some(CommitmentConfig::processed()), + encoding: None, + accounts: None, + min_context_slot: None, + }).await + { + Ok(resp) => { + // println!("[QVN] SimulationResponse: {:?}", resp); + + // TODO: catch common simulation errors and figure out how to convert to our Anchor error + if resp.value.err.is_some() { + println!("[QVN] SimulationErrors: {:?}", resp.value.err.unwrap()); + + return Err( + SbError::FunctionResultFailoverError( + 210, // improve the handling here + Arc::new(SbError::Message("UnknownSimulationError")) + ) + ); + } + } + Err(e) => { + println!("[QVN] SimulationError: {:?}", e); + + if let Some(TransactionError::InstructionError(idx, e)) = e.get_transaction_error() { + if idx > 0 { + return Err( + SbError::FunctionResultFailoverError( + SbFunctionError::CallbackError.as_u8(), + Arc::new(e) + ) + ); + } + } + + return Err( + SbError::FunctionResultFailoverError( + 210, // improve the handling here + Arc::new(e) + ) + ); + } + } + + // 8. Return the partially signed txn that is ready to send + // If we avoid signing inside this function, then we do NOT need the verifier keypairs to + // validate the function result + + Ok(tx) + } + + /// Retrieve the function's SwitchboardWallet from the cache if updated within the timeout, or fetch from on-chain RPC. + /// + /// # Arguments + /// + /// * `function_pubkey` - A `Pubkey` for the given function account. + /// + /// # Returns + /// + /// Returns a `Result` containing the `Pubkey` of the function's SwitchboardWallet if successful, or an `SbError` if an error occurred. + async fn get_function_escrow_wallet(&self, function_pubkey: Pubkey) -> Result { + if let Some(timeout) = self.cache.timeout { + let timeout: i64 = timeout.try_into().unwrap_or_default(); + self.cache.function_escrow_wallet.remove_if(&function_pubkey, |_k, entry| { + unix_timestamp() - entry.timestamp > timeout + }); + } + + if + let Some(function_escrow_cache_entry) = self.cache.function_escrow_wallet.get( + &function_pubkey + ) + { + return Ok(function_escrow_cache_entry.pubkey); + } + + let function_data = FunctionAccountData::fetch_async( + &self.rpc, + function_pubkey + ).await.unwrap(); + + self.cache.function_escrow_wallet.insert(function_pubkey, CacheEntry { + pubkey: function_data.escrow_wallet, + timestamp: unix_timestamp(), + }); + + Ok(function_data.escrow_wallet) + } + + /// Retrieve the function routine's SwitchboardWallet from the cache if updated within the timeout, or fetch from on-chain RPC. + /// + /// # Arguments + /// + /// * `routine_pubkey` - A `Pubkey` for the given function routine account. + /// + /// # Returns + /// + /// Returns a `Result` containing the `Pubkey` of the function routine's SwitchboardWallet if successful, or an `SbError` if an error occurred. + async fn get_routine_escrow_wallet(&self, routine_pubkey: Pubkey) -> Result { + if let Some(timeout) = self.cache.timeout { + let timeout: i64 = timeout.try_into().unwrap_or_default(); + self.cache.routine_escrow_wallet.remove_if(&routine_pubkey, |_k, entry| { + unix_timestamp() - entry.timestamp > timeout + }); + } + + if + let Some(routine_escrow_cache_entry) = self.cache.routine_escrow_wallet.get( + &routine_pubkey + ) + { + return Ok(routine_escrow_cache_entry.pubkey); + } + + let routine_data = FunctionRoutineAccountData::fetch_async( + &self.rpc, + routine_pubkey + ).await.unwrap(); + + self.cache.routine_escrow_wallet.insert(routine_pubkey, CacheEntry { + pubkey: routine_data.escrow_wallet, + timestamp: unix_timestamp(), + }); + + Ok(routine_data.escrow_wallet) + } + + /// Sign the transaction with the payer and verifier_enclave_signer keypair and send to the network + async fn send_txn(&self, tx: &mut Transaction) -> Result { + let verifier_enclave_keypair = self.get_verifier_enclave_signer().await?; + + let recent_blockhash = tx.message.recent_blockhash; + let keypairs = &[&*self.payer, &*verifier_enclave_keypair]; + + tx.try_partial_sign(keypairs, recent_blockhash).map_err(|e| SbError::CustomError { + message: "Failed to sign the Solana transaction with the payer and verifier_enclave_signer keypair".to_string(), + source: Arc::new(e), + })?; + + match self.rpc.send_transaction(tx).await { + Ok(signature) => { + println!("[QVN] Sent transaction with signature {:?}", signature); + Ok(signature) + } + Err(e) => { + println!("[QVN] Failed to send transaction: {:?}", e); + Err(SbError::CustomError { + message: "Failed to send transaction".to_string(), + source: Arc::new(e), + }) + } + } + } + + async fn build_function_verify_ix( + &self, + function: Pubkey, + enclave_signer: Option, + params: FunctionVerifyParams + ) -> Result { + let verifier_accounts = self.get_verify_accounts().await; + + let function_escrow = self.get_function_escrow_wallet(function).await?; + + let ix = FunctionVerify::build_ix( + &(FunctionVerifyAccounts { + function, + function_enclave_signer: enclave_signer.unwrap_or( + verifier_accounts.verifier_enclave_signer + ), + function_escrow, + verifier: verifier_accounts.verifier, + verifier_enclave_signer: verifier_accounts.verifier_enclave_signer, + reward_receiver: verifier_accounts.reward_receiver, + attestation_queue: verifier_accounts.attestation_queue, + queue_authority: verifier_accounts.queue_authority, + }), + ¶ms + )?; + + Ok(ix) + } + + async fn build_request_verify_ix( + &self, + function: Pubkey, + request: Pubkey, + enclave_signer: Option, + params: FunctionRequestVerifyParams + ) -> Result { + let verifier_accounts = self.get_verify_accounts().await; + + let function_escrow = self.get_function_escrow_wallet(function).await?; + let function_escrow_token_wallet = find_associated_token_address( + &function_escrow, + &NativeMint::ID + ); + + let ix = FunctionRequestVerify::build_ix( + &(FunctionRequestVerifyAccounts { + request, + function_enclave_signer: enclave_signer.unwrap_or( + verifier_accounts.verifier_enclave_signer + ), + function, + function_escrow_token_wallet: Some(function_escrow_token_wallet), // optional + verifier: verifier_accounts.verifier, + verifier_enclave_signer: verifier_accounts.verifier_enclave_signer, + reward_receiver: verifier_accounts.reward_receiver, + attestation_queue: verifier_accounts.attestation_queue, + queue_authority: verifier_accounts.queue_authority, + }), + ¶ms + )?; + + Ok(ix) + } + + async fn build_routine_verify_ix( + &self, + function: Pubkey, + routine: Pubkey, + enclave_signer: Option, + params: FunctionRoutineVerifyParams + ) -> Result { + let verifier_accounts = self.get_verify_accounts().await; + + let function_escrow = self.get_function_escrow_wallet(function).await?; + let function_escrow_token_wallet = find_associated_token_address( + &function_escrow, + &NativeMint::ID + ); + + let routine_escrow = self.get_routine_escrow_wallet(routine).await?; + + let ix = FunctionRoutineVerify::build_ix( + &(FunctionRoutineVerifyAccounts { + routine, + escrow_wallet: routine_escrow, + function_enclave_signer: enclave_signer.unwrap_or( + verifier_accounts.verifier_enclave_signer + ), + function, + function_escrow_token_wallet: Some(function_escrow_token_wallet), // optional + verifier: verifier_accounts.verifier, + verifier_enclave_signer: verifier_accounts.verifier_enclave_signer, + reward_receiver: verifier_accounts.reward_receiver, + attestation_queue: verifier_accounts.attestation_queue, + queue_authority: verifier_accounts.queue_authority, + }), + ¶ms + )?; + + Ok(ix) + } + + /// Produce the oracle failover transaction if the FunctionResult validation returned any errors + async fn produce_failover_tx( + &self, + function_result: &FunctionResult, + error_code: Option + ) -> Result { + let mut function_result = function_result.clone(); + if let Some(error_code) = error_code { + function_result.set_error_code(error_code); + } + + let solana_function_result = if + let Ok(switchboard_common::ChainResultInfo::Solana(chain_result_info)) = + function_result.chain_result_info() + { + chain_result_info + } else { + SolanaFunctionResult::default() + }; + + let function = Pubkey::try_from_slice( + function_result.fn_key().unwrap().as_slice() + ).unwrap(); + + let timestamp = unix_timestamp(); + let next_allowed_timestamp = timestamp + 30; + + let verify_ixn: Instruction = match solana_function_result { + // TODO: implement V0 correctly so it can handle function_verify and function_request_verify + SolanaFunctionResult::V0(_) => { + self.build_function_verify_ix(function, None, FunctionVerifyParams { + observed_time: timestamp, + next_allowed_timestamp, + error_code: function_result.error_code(), + mr_enclave: [0; 32], + }).await? + } + SolanaFunctionResult::V1(v) => + match v.request_type { + SolanaFunctionRequestType::Routine(routine_pubkey_bytes) => { + let routine_pubkey = Pubkey::try_from_slice( + &routine_pubkey_bytes[..] + ).unwrap(); + + self.build_routine_verify_ix( + function, + routine_pubkey, + None, + FunctionRoutineVerifyParams { + mr_enclave: [0; 32], + error_code: function_result.error_code(), + observed_time: timestamp, + next_allowed_timestamp: 0, + container_params_hash: [0u8; 32], + } + ).await? + } + SolanaFunctionRequestType::Request(request_pubkey_bytes) => { + let request_pubkey = Pubkey::try_from_slice( + &request_pubkey_bytes[..] + ).unwrap(); + + self.build_request_verify_ix( + function, + request_pubkey, + None, + FunctionRequestVerifyParams { + mr_enclave: [0; 32], + error_code: function_result.error_code(), + observed_time: timestamp, + request_slot: 0, + container_params_hash: [0u8; 32], + } + ).await? + } + SolanaFunctionRequestType::Function(_) => { + self.build_function_verify_ix(function, None, FunctionVerifyParams { + observed_time: timestamp, + next_allowed_timestamp, + error_code: function_result.error_code(), + mr_enclave: [0; 32], + }).await? + } + } + }; + + let recent_blockhash = self.rpc.get_latest_blockhash().await.unwrap_or_default(); + // .map_err(|_| SbError::Message("NetworkErr"))?; + + let payer: Pubkey = signer_to_pubkey(self.payer.clone()).unwrap(); + + let mut message = Message::new(&[verify_ixn], Some(&payer)); + message.recent_blockhash = recent_blockhash; + + Ok(Transaction::new_unsigned(message)) + } + + /// Build the transaction from the emitted serialized_tx Vec and perform the following validation: + /// * Contains at least one instruction + /// * First instruction has at least 8 bytes of data + /// * First instruction is pointed at the Switchboard Attestation PID + /// * First instruction is one of FunctionVerify, FunctionRoutineVerify, or FunctionRequestVerify + /// * The verifier's payer and enclave_signer is not used in any other instructions + async fn build_and_verify_txn( + &self, + solana_function_result: &SolanaFunctionResult + ) -> Result<(Transaction, SolanaFunctionRequestType, u8), SbError> { + let tx: Transaction = bincode + ::deserialize(&solana_function_result.serialized_tx()) + .map_err(|_| { + SbError::FunctionResultFailoverError( + 200, + Arc::new(SbError::FunctionResultError("TransactionDeserializationError")) + ) + })?; + + // Verify there is at least one instruction + if tx.message.instructions.is_empty() { + return Err( + SbError::FunctionResultFailoverError( + 200, + Arc::new(SbError::FunctionResultIxError("EmptyInstructions")) + ) + ); + } + + let untrusted_verify_idx: u8 = 0; + let untrusted_verify_ixn = &tx.message.instructions[untrusted_verify_idx as usize]; + + if untrusted_verify_ixn.data.len() < 8 { + return Err( + SbError::FunctionResultFailoverError( + 200, + Arc::new(SbError::FunctionResultIxError("MissingDiscriminator")) + ) + ); + } + + // Verify the first ixn is pointed at the Switchboard Attestation PID + let untrusted_verify_pid_idx = tx.message.account_keys + .iter() + .position(|&x| x == SWITCHBOARD_ATTESTATION_PROGRAM_ID); + if + untrusted_verify_pid_idx.is_none() || + (untrusted_verify_ixn.program_id_index as usize) != untrusted_verify_pid_idx.unwrap() + { + return Err( + SbError::FunctionResultFailoverError( + 200, + Arc::new(SbError::FunctionResultIxError("InvalidPid")) + ) + ); + } + + let mut ixn_discriminator = [0u8; 8]; + ixn_discriminator.copy_from_slice(&untrusted_verify_ixn.data[0..8]); + + let request_type = match solana_function_result { + // Derive the request type from the first ixns discriminator if missing + SolanaFunctionResult::V0(_) => + (match ixn_discriminator { + FunctionVerify::DISCRIMINATOR => + Ok( + SolanaFunctionRequestType::Function( + tx.message.account_keys[untrusted_verify_ixn.accounts[0] as usize] + .to_bytes() + .to_vec() + ) + ), + FunctionRequestVerify::DISCRIMINATOR => + Ok( + SolanaFunctionRequestType::Request( + tx.message.account_keys[untrusted_verify_ixn.accounts[0] as usize] + .to_bytes() + .to_vec() + ) + ), + FunctionRoutineVerify::DISCRIMINATOR => + Ok( + SolanaFunctionRequestType::Routine( + tx.message.account_keys[untrusted_verify_ixn.accounts[0] as usize] + .to_bytes() + .to_vec() + ) + ), + _ => + Err( + SbError::FunctionResultFailoverError( + 200, + Arc::new(SbError::FunctionResultIxError("InvalidInstructionData")) + ) + ), + })?, + // 1. Verify the ixn discriminator + // 2. Verify the inner pubkey is correctly set + SolanaFunctionResult::V1(v1) => + match &v1.request_type { + SolanaFunctionRequestType::Routine(routine_pubkey_bytes) => { + if ixn_discriminator != FunctionRoutineVerify::DISCRIMINATOR { + return Err(SbError::FunctionResultInvalidData); + } + if + routine_pubkey_bytes != + &tx.message.account_keys[untrusted_verify_ixn.accounts[0] as usize] + .to_bytes() + .to_vec() + { + return Err(SbError::FunctionResultInvalidData); + } + v1.request_type.clone() + } + SolanaFunctionRequestType::Request(request_pubkey_bytes) => { + if ixn_discriminator != FunctionRequestVerify::DISCRIMINATOR { + return Err(SbError::FunctionResultInvalidData); + } + if + request_pubkey_bytes != + &tx.message.account_keys[untrusted_verify_ixn.accounts[0] as usize] + .to_bytes() + .to_vec() + { + return Err(SbError::FunctionResultInvalidData); + } + v1.request_type.clone() + } + SolanaFunctionRequestType::Function(function_pubkey_bytes) => { + if ixn_discriminator != FunctionVerify::DISCRIMINATOR { + return Err(SbError::FunctionResultInvalidData); + } + if + function_pubkey_bytes != + &tx.message.account_keys[untrusted_verify_ixn.accounts[0] as usize] + .to_bytes() + .to_vec() + { + return Err(SbError::FunctionResultInvalidData); + } + v1.request_type.clone() + } + } + }; + + // validate the verifier_enclave_signer and payer are not used in any downstream ixns + if tx.message.instructions.len() > 1 { + let verifier_enclave_signer = *self.get_verifier_enclave_pubkey().await; + let enclave_signer_idx = tx.message.account_keys + .iter() + .position(|&x| x == verifier_enclave_signer); + let payer_idx = tx.message.account_keys.iter().position(|&x| x == self.payer.pubkey()); + for ix in &tx.message.instructions[1..] { + for account_idx in &ix.accounts { + if Some(*account_idx as usize) == enclave_signer_idx { + return Err(SbError::FunctionResultIllegalAccount); + } + if Some(*account_idx as usize) == payer_idx { + return Err(SbError::FunctionResultIllegalAccount); + } + } + } + } + + Ok((tx, request_type, untrusted_verify_idx)) + } + + /// Deserialize the verify instructions parameters and return a cleaned up version of the params based on the request type + fn get_params( + request_type: &SolanaFunctionRequestType, + verify_param_bytes: Vec + ) -> Result { + match request_type { + SolanaFunctionRequestType::Routine(_) => { + let params = FunctionRoutineVerifyParams::deserialize( + &mut verify_param_bytes.as_slice() + ).map_err(|_e| { + SbError::FunctionResultFailoverError( + 200, + Arc::new(SbError::FunctionResultIxError("InvalidInstructionData")) + ) + })?; + + Ok(FunctionValidatorVerifyParams { + mr_enclave: params.mr_enclave, + error_code: params.error_code, + observed_time: params.observed_time, + container_params_hash: params.container_params_hash, + next_allowed_timestamp: params.next_allowed_timestamp, + ..Default::default() + }) + } + SolanaFunctionRequestType::Request(_) => { + let params = FunctionRequestVerifyParams::deserialize( + &mut verify_param_bytes.as_slice() + ).map_err(|_e| { + SbError::FunctionResultFailoverError( + 200, + Arc::new(SbError::FunctionResultIxError("InvalidInstructionData")) + ) + })?; + + Ok(FunctionValidatorVerifyParams { + mr_enclave: params.mr_enclave, + error_code: params.error_code, + observed_time: params.observed_time, + container_params_hash: params.container_params_hash, + request_slot: params.request_slot, + ..Default::default() + }) + } + SolanaFunctionRequestType::Function(_) => { + let params = FunctionVerifyParams::deserialize( + &mut verify_param_bytes.as_slice() + ).map_err(|_e| { + SbError::FunctionResultFailoverError( + 200, + Arc::new(SbError::FunctionResultIxError("InvalidInstructionData")) + ) + })?; + + Ok(FunctionValidatorVerifyParams { + mr_enclave: params.mr_enclave, + error_code: params.error_code, + observed_time: params.observed_time, + next_allowed_timestamp: params.next_allowed_timestamp, + ..Default::default() + }) + } + } + } + + /// Return the accounts used by this verifier to verify the function result + async fn get_verify_accounts(&self) -> FunctionResultValidatorAccounts { + FunctionResultValidatorAccounts { + verifier: *self.verifier, + verifier_enclave_signer: *self.get_verifier_enclave_pubkey().await, + payer: self.payer.pubkey(), + reward_receiver: *self.reward_receiver, + attestation_queue: *self.attestation_queue, + queue_authority: *self.queue_authority, + } + } + + /// Build a new version of the verify ixn for basic sanity checking + async fn build_trusted_verify_ixn( + &self, + function_pubkey: &Pubkey, + function_enclave_signer: &Pubkey, + request_type: &SolanaFunctionRequestType, + untrusted_params: &FunctionValidatorVerifyParams + ) -> Result { + let trusted_verify_ixn: Instruction = match &request_type { + SolanaFunctionRequestType::Routine(routine_pubkey_bytes) => { + self.build_routine_verify_ix( + *function_pubkey, + Pubkey::try_from_slice(&routine_pubkey_bytes[..]).unwrap(), + Some(*function_enclave_signer), + FunctionRoutineVerifyParams { + observed_time: untrusted_params.observed_time, + next_allowed_timestamp: untrusted_params.next_allowed_timestamp, + error_code: untrusted_params.error_code, + mr_enclave: untrusted_params.mr_enclave, + container_params_hash: untrusted_params.container_params_hash, + } + ).await? + } + SolanaFunctionRequestType::Request(request_pubkey_bytes) => { + self.build_request_verify_ix( + *function_pubkey, + Pubkey::try_from_slice(&request_pubkey_bytes[..]).unwrap(), + Some(*function_enclave_signer), + FunctionRequestVerifyParams { + mr_enclave: untrusted_params.mr_enclave, + error_code: untrusted_params.error_code, + observed_time: untrusted_params.observed_time, + container_params_hash: untrusted_params.container_params_hash, + + request_slot: untrusted_params.request_slot, + } + ).await? + } + SolanaFunctionRequestType::Function(_) => { + self.build_function_verify_ix( + *function_pubkey, + Some(*function_enclave_signer), + FunctionVerifyParams { + mr_enclave: untrusted_params.mr_enclave, + error_code: untrusted_params.error_code, + observed_time: untrusted_params.observed_time, + next_allowed_timestamp: untrusted_params.next_allowed_timestamp, + } + ).await? + } + }; + + Ok(trusted_verify_ixn) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::str::FromStr; + use tokio::sync::OnceCell; + + // lazy loaded validator, having trouble using this with anchor28 - runtime crashing after async closure exits + static VALIDATOR: OnceCell = OnceCell::const_new(); + static FUNCTION: OnceCell = OnceCell::const_new(); + + // 6vLX2GC3FQ6HtXe5K2b3CYePToB7bdCHQs6nPEFwg6bH + const DEMO_FUNCTION_PUBKEY_BYTES: [u8; 32] = [ + 87, 244, 73, 65, 67, 23, 129, 192, 3, 231, 155, 123, 4, 35, 131, 151, 109, 104, 41, 161, + 81, 238, 54, 71, 208, 241, 158, 58, 108, 158, 156, 240, + ]; + + /// Build a buffer from a valid quote and replace the mrenclave and report data with the provided params + fn build_quote_buffer(enclave_signer: &Keypair, mrenclave: [u8; 32]) -> Vec { + let mut quote_buffer = [0u8; 1456]; + + // First we copy from a valid quote so we start with some good data + let raw_sgx_quote_bytes = include_bytes!("../../fixtures/v2_quote.bin"); + quote_buffer[0..1456].copy_from_slice(&raw_sgx_quote_bytes[0..1456]); + + // Set the mrenclave + quote_buffer[112..144].copy_from_slice(&mrenclave); + + // Set the report data + quote_buffer[368..400].copy_from_slice( + Sha256::digest(enclave_signer.pubkey().to_bytes()).as_slice() + ); + + // TODO: sign the report and add the signature so we can fully verify the quote if we need to + + quote_buffer.to_vec() + } + + // Async getter for our OnceLocked validator + async fn get_devnet_function_result_validator() -> &'static FunctionResultValidator { + VALIDATOR.get_or_init(|| async { + // We dont do any signature verification inside the validate function so these can be dummy keypairs + let payer = load_keypair_fs("/Users/gally/.config/solana/id.json").unwrap(); + + // Devnet verifier oracle + // let accounts = FunctionResultValidatorInitAccounts { + // verifier_pubkey: Pubkey::from_str("FT41PAvhJj7YqQwuALeSr2PDh7kEub2wb9Ve64jPjDXk") + // .unwrap(), + // attestation_queue: Pubkey::from_str("CkvizjVnm2zA5Wuwan34NhVT3zFc7vqUyGnA6tuEF5aE") + // .unwrap(), + // queue_authority: Pubkey::from_str("2KgowxogBrGqRcgXQEmqFvC3PGtCu66qERNJevYW8Ajh") + // .unwrap(), + // reward_receiver: Pubkey::from_str("CRXGEGMz4RoRyjXhktMp7SzkcFLV3uevZcr2yCnnWpBt") + // .unwrap(), + // }; + + // TODO: load this using the env variable RPC_URL + let cluster = Cluster::from_str( + "https://api.devnet.solana.com" + ).unwrap_or(Cluster::Devnet); + + let client = AnchorClient::new_with_options( + cluster, + payer.clone(), + CommitmentConfig::processed() + ); + let program = get_attestation_program(&client).unwrap(); + + let rpc = Arc::new(program.async_rpc()); + + let bootstrapped_queue = BootstrappedAttestationQueue::get_or_create_from_seed( + &rpc, + payer.clone(), + None, + None + ).await.unwrap(); + let accounts = FunctionResultValidatorInitAccounts { + verifier: bootstrapped_queue.verifier, + attestation_queue: bootstrapped_queue.attestation_queue, + queue_authority: bootstrapped_queue.queue_authority, + reward_receiver: Pubkey::from_str( + "CRXGEGMz4RoRyjXhktMp7SzkcFLV3uevZcr2yCnnWpBt" + ).unwrap(), + }; + + let function_pubkey = Pubkey::from(DEMO_FUNCTION_PUBKEY_BYTES); + + // let verifier_data = VerifierAccountData::fetch(&program.rpc(), accounts.verifier_pubkey).unwrap(); + // let function_data = FunctionAccountData::fetch(&program.rpc(), function_pubkey).unwrap(); + + // let (verifier_data_result, function_data_result) = tokio::join!( + // VerifierAccountData::fetch_async(&rpc, accounts.verifier_pubkey), + // FunctionAccountData::fetch_async(&rpc, function_pubkey) + // ); + + // let verifier_data = verifier_data_result.unwrap(); + // let function_data = function_data_result.unwrap(); + + let verifier_data = VerifierAccountData::fetch_async( + &rpc, + accounts.verifier + ).await.unwrap(); + let function_data = FunctionAccountData::fetch_async( + &rpc, + function_pubkey + ).await.unwrap(); + + let cache = FunctionResultValidatorCache { + timeout: None, + function_escrow_wallet: Arc::new(DashMap::with_capacity(10_000)), + routine_escrow_wallet: Arc::new(DashMap::with_capacity(10_000)), + }; + + cache.function_escrow_wallet.insert(function_pubkey, CacheEntry { + pubkey: function_data.escrow_wallet, + timestamp: unix_timestamp(), + }); + + FunctionResultValidator::new( + Arc::new(RwLock::new(client)), + rpc, + payer.clone(), + FunctionResultValidatorSigner::Simulation( + Arc::new(verifier_data.enclave.enclave_signer) + ), + &accounts, + |_quote_bytes, _observed_time| true, + Some(cache) + ) + }).await + } + + /// Async getter for our dedicated function pubkey + async fn get_function_pubkey() -> &'static Pubkey { + FUNCTION.get_or_init(|| async { + let validator = get_devnet_function_result_validator().await; + + let function_pubkey = FunctionAccountData::get_or_create_from_seed( + &validator.rpc, + validator.payer.clone(), + *validator.attestation_queue, + None, + None + ).await.unwrap(); + + // let function_pubkey = Pubkey::from(DEMO_FUNCTION_PUBKEY_BYTES); + function_pubkey + }).await + } + + /// Initialize the logger, the validator, and request an airdrop if the payer is out of funds + async fn setup_test_validator() -> &'static FunctionResultValidator { + let validator = get_devnet_function_result_validator().await; + + let payer_balance = validator.rpc.get_balance(&validator.payer.pubkey()).await.unwrap(); + + if payer_balance == 0 { + let sig = validator.rpc + .request_airdrop(&validator.payer.pubkey(), 1_000_000_000).await + .unwrap(); + println!("[Payer] Airdrop requested. Txn Signature: {}", sig); + } + + validator + } + + #[tokio::test] + async fn test_function_validation() { + // Setup logging + if let Err(_e) = std::env::var("RUST_LOG") { + std::env::set_var("RUST_LOG", "debug"); + } + + json_env_logger::try_init().unwrap(); + + let validator = setup_test_validator().await; + + let function_enclave_signer = Keypair::new(); + + let sgx_quote_bytes = build_quote_buffer( + &function_enclave_signer, + DEFAULT_FUNCTION_MR_ENCLAVE + ); + let _sgx_quote = sgx_quote::Quote::parse(&sgx_quote_bytes[..]).unwrap(); + + // let mut mr_enclave = [0u8; 32]; + // mr_enclave.copy_from_slice(sgx_quote.isv_report.mrenclave); + + // Function + let function_pubkey = *get_function_pubkey().await; + + let timestamp = unix_timestamp(); + let next_allowed_timestamp = timestamp + 30; + + let function_verify_ix = validator + .build_function_verify_ix( + function_pubkey, + Some(function_enclave_signer.pubkey()), + FunctionVerifyParams { + mr_enclave: DEFAULT_FUNCTION_MR_ENCLAVE, + error_code: 0, + observed_time: timestamp, + next_allowed_timestamp, + } + ).await + .unwrap(); + + let ixs = vec![function_verify_ix]; + let message = Message::new(&ixs, Some(&validator.payer.pubkey())); + let blockhash = validator.rpc.get_latest_blockhash().await.unwrap_or_default(); + let mut tx = solana_sdk::transaction::Transaction::new_unsigned(message); + tx.partial_sign(&[&function_enclave_signer], blockhash); + let serialized_tx = bincode::serialize(&tx).unwrap(); + + let function_result = FunctionResult::V1(FunctionResultV1 { + quote: sgx_quote_bytes.to_vec(), + signer: function_enclave_signer.pubkey().to_bytes().to_vec(), + signature: vec![], + chain_result_info: ChainResultInfo::Solana( + SolanaFunctionResult::V1(SolanaFunctionResultV1 { + serialized_tx, + fn_key: function_pubkey.to_bytes().to_vec(), + request_type: SolanaFunctionRequestType::Function( + function_pubkey.to_bytes().to_vec() + ), + request_hash: [0u8; 32].to_vec(), + }) + ), + error_code: 0, + }); + + let result = validator.validate(&function_result).await; + // println!("[Function] Result: {:?}", result); + assert!(result.is_ok()); + } + + #[tokio::test] + async fn test_request_validation() { + // Setup logging + if let Err(_e) = std::env::var("RUST_LOG") { + std::env::set_var("RUST_LOG", "debug"); + } + + json_env_logger::try_init().unwrap(); + + let validator = setup_test_validator().await; + + let function_enclave_signer = Keypair::new(); + + let sgx_quote_bytes = build_quote_buffer( + &function_enclave_signer, + DEFAULT_FUNCTION_MR_ENCLAVE + ); + let _sgx_quote = sgx_quote::Quote::parse(&sgx_quote_bytes[..]).unwrap(); + + // let mut mr_enclave = [0u8; 32]; + // mr_enclave.copy_from_slice(sgx_quote.isv_report.mrenclave); + + // Function + let function_pubkey = *get_function_pubkey().await; + + let request_pubkey = FunctionRequestAccountData::get_or_create_from_seed( + &validator.rpc, + validator.payer.clone(), + function_pubkey, + None, + None + ).await.unwrap(); + + // Meh, using devnet causes the oracles to respond which breaks the tests. + // Need a dedicated queue for this. + let request_data = FunctionRequestAccountData::fetch_async( + &validator.rpc, + request_pubkey + ).await.unwrap(); + + let verify_ix = validator + .build_request_verify_ix( + function_pubkey, + request_pubkey, + Some(function_enclave_signer.pubkey()), + FunctionRequestVerifyParams { + mr_enclave: DEFAULT_FUNCTION_MR_ENCLAVE, + error_code: 0, + observed_time: unix_timestamp(), + request_slot: request_data.active_request.request_slot, + container_params_hash: request_data.container_params_hash, + } + ).await + .unwrap(); + + let ixs = vec![verify_ix]; + let message = Message::new(&ixs, Some(&validator.payer.pubkey())); + let blockhash = validator.rpc.get_latest_blockhash().await.unwrap_or_default(); + let mut tx = solana_sdk::transaction::Transaction::new_unsigned(message); + tx.partial_sign(&[&function_enclave_signer], blockhash); + let serialized_tx = bincode::serialize(&tx).unwrap(); + + let function_result = FunctionResult::V1(FunctionResultV1 { + quote: sgx_quote_bytes.to_vec(), + signer: function_enclave_signer.pubkey().to_bytes().to_vec(), + signature: vec![], + chain_result_info: ChainResultInfo::Solana( + SolanaFunctionResult::V1(SolanaFunctionResultV1 { + serialized_tx, + fn_key: function_pubkey.to_bytes().to_vec(), + request_type: SolanaFunctionRequestType::Request( + request_pubkey.to_bytes().to_vec() + ), + request_hash: [0u8; 32].to_vec(), + }) + ), + error_code: 0, + }); + + let result = validator.validate(&function_result).await; + // println!("[Request] Result: {:?}", result); + assert!(result.is_ok()); + } +} + +fn parse_mrenclave_hex(hex_str: &str) -> Result<[u8; 32], SbError> { + let mut mrenclave = [0u8; 32]; + + let hex_bytes = hex::decode(hex_str).map_err(|_e| SbError::Message("InvalidHex"))?; + if hex_bytes.len() != 32 { + return Err(SbError::Message("InvalidHex")); + } + + mrenclave.copy_from_slice(&hex_bytes); + Ok(mrenclave) +} + +async fn print_function_verify_accounts(function_verify_ix: Instruction, rpc: Arc) { + let verify_ix_accounts: Vec = function_verify_ix.accounts + .clone() + .iter() + .map(|a| a.pubkey) + .collect(); + + println!("#1 {:<24}: {:?}", "Function", verify_ix_accounts.get(0).unwrap()); + println!("#2 {:<24}: {:?}", "FunctionEnclaveSigner", verify_ix_accounts.get(1).unwrap()); + println!("#3 {:<24}: {:?}", "Verifier", verify_ix_accounts.get(2).unwrap()); + println!("#4 {:<24}: {:?}", "VerifierEnclaveSigner", verify_ix_accounts.get(3).unwrap()); + println!("#5 {:<24}: {:?}", "VerifierPermission", verify_ix_accounts.get(4).unwrap()); + println!("#6 {:<24}: {:?}", "EscrowWallet", verify_ix_accounts.get(5).unwrap()); + println!("#7 {:<24}: {:?}", "EscrowTokenWallet", verify_ix_accounts.get(6).unwrap()); + println!("#8 {:<24}: {:?}", "Receiver", verify_ix_accounts.get(7).unwrap()); + println!("#9 {:<24}: {:?}", "Attestation Queue", verify_ix_accounts.get(8).unwrap()); + + let account_infos = rpc.get_multiple_accounts(&verify_ix_accounts).await.unwrap(); + + for (i, account) in account_infos.iter().enumerate() { + // #2 and #4 are enclave generated keypairs and can be skipped + if account.is_none() && i != 1 && i != 3 { + println!("Account #{} is missing", i + 1); + } + } +} + +// TODO: Create a way to initialize a BoostrappedAttestationQueue using the payer's secret key, +// some base seed, and a hash of the parameters. This will allow us to create a new queue for each +// config and easily build getter methods to retrieve them. diff --git a/rust/switchboard-solana/src/decimal.rs b/rust/switchboard-solana/src/decimal.rs index 7f6d5f935..115d994b3 100644 --- a/rust/switchboard-solana/src/decimal.rs +++ b/rust/switchboard-solana/src/decimal.rs @@ -100,9 +100,7 @@ impl Ord for SwitchboardDecimal { impl PartialOrd for SwitchboardDecimal { fn partial_cmp(&self, other: &Self) -> Option { - let s: Decimal = self.try_into().unwrap(); - let other: Decimal = other.try_into().unwrap(); - s.partial_cmp(&other) + Some(self.cmp(other)) } fn lt(&self, other: &Self) -> bool { let s: Decimal = self.try_into().unwrap(); diff --git a/rust/switchboard-solana/src/error.rs b/rust/switchboard-solana/src/error.rs index 3d9d6a65b..e04f5e992 100644 --- a/rust/switchboard-solana/src/error.rs +++ b/rust/switchboard-solana/src/error.rs @@ -43,10 +43,23 @@ pub enum SwitchboardError { InvalidEnclaveSigner, #[msg("The provided mint did not match the wrapped SOL mint address")] InvalidNativeMint, + #[msg("This account has zero mr_enclaves defined")] + MrEnclavesEmpty, + InvalidMrEnclave, + #[msg("The FunctionAccount status is not active (1)")] + FunctionNotReady, + #[msg("The FunctionAccount has set requests_disabled to true and disabled this action")] + UserRequestsDisabled, + FunctionRoutinesDisabled, + #[msg( + "The PermissionAccount is missing the required flags for this action. Check the queues config to see which permissions are required" + )] + PermissionDenied, + ConfigParameterLocked, } use crate::cfg_client; cfg_client! { - pub use switchboard_common::{Error as SwitchboardClientError}; + pub use switchboard_common::{ SbError, SbFunctionError }; } diff --git a/rust/switchboard-solana/src/events.rs b/rust/switchboard-solana/src/events.rs new file mode 100644 index 000000000..69daa33bb --- /dev/null +++ b/rust/switchboard-solana/src/events.rs @@ -0,0 +1 @@ +pub use crate::attestation_program::events::*; diff --git a/rust/switchboard-solana/src/instructions.rs b/rust/switchboard-solana/src/instructions.rs index feb6e214b..d35d2b324 100644 --- a/rust/switchboard-solana/src/instructions.rs +++ b/rust/switchboard-solana/src/instructions.rs @@ -4,8 +4,10 @@ pub use crate::oracle_program::instructions::{ }; pub use crate::attestation_program::instructions::{ - FunctionClose, FunctionInit, FunctionRequestClose, FunctionRequestInit, + AttestationPermissionInit, AttestationPermissionSet, AttestationQueueAddMrEnclave, + AttestationQueueInit, FunctionClose, FunctionInit, FunctionRequestClose, FunctionRequestInit, FunctionRequestInitAndTrigger, FunctionRequestSetConfig, FunctionRequestTrigger, - FunctionRequestVerify, FunctionSetEscrow, FunctionTrigger, FunctionVerify, WalletFund, - WalletInit, WalletWithdraw, + FunctionRequestVerify, FunctionRoutineInit, FunctionRoutineVerify, FunctionSetEscrow, + FunctionTrigger, FunctionVerify, VerifierHeartbeat, VerifierInit, VerifierQuoteRotate, + VerifierQuoteVerify, WalletFund, WalletInit, WalletWithdraw, }; diff --git a/rust/switchboard-solana/src/lib.rs b/rust/switchboard-solana/src/lib.rs index 818630a32..41a48346d 100644 --- a/rust/switchboard-solana/src/lib.rs +++ b/rust/switchboard-solana/src/lib.rs @@ -95,7 +95,7 @@ mod macros; -use solana_program::{declare_id, pubkey, pubkey::Pubkey}; +use solana_program::pubkey; pub mod decimal; pub use decimal::*; @@ -116,6 +116,12 @@ pub use seeds::*; pub mod utils; pub use utils::*; +pub mod events; +pub use events::*; + +pub mod program_id; +pub use program_id::*; + pub mod accounts; pub mod instructions; pub mod types; @@ -123,23 +129,28 @@ pub mod types; pub mod prelude; cfg_client! { - pub mod client; + mod client; pub use client::*; } +cfg_ipfs! { + pub mod ipfs { + pub use switchboard_common::ipfs::*; + } +} + cfg_secrets! { pub mod secrets; pub use secrets::*; } -/// Program id for the Switchboard oracle program -/// SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f -pub const SWITCHBOARD_PROGRAM_ID: Pubkey = pubkey!("SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f"); - -/// Program id for the Switchboard oracle program -/// sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx -pub const SWITCHBOARD_ATTESTATION_PROGRAM_ID: Pubkey = - pubkey!("sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx"); +cfg_macros! { + // Futures crate is needed by the proc_macro + pub use futures; + pub use futures::Future; + pub use switchboard_solana_macros::switchboard_function; + pub use switchboard_solana_macros::sb_error; +} /// The minimum number of slots before a request is considered expired. pub const MINIMUM_USERS_NUM_SLOTS_UNTIL_EXPIRATION: u64 = 150; // 1 min at 400ms/slot @@ -147,6 +158,6 @@ pub const MINIMUM_USERS_NUM_SLOTS_UNTIL_EXPIRATION: u64 = 150; // 1 min at 400ms /// The default number of slots before a request expires. pub const DEFAULT_USERS_NUM_SLOTS_UNTIL_EXPIRATION: u64 = 2250; // 15 min at 400ms/slot -pub const DEFAULT_USERS_CONTAINER_PARAMS_LEN: u32 = 256; +pub const DEFAULT_MAX_CONTAINER_PARAMS_LEN: u32 = 256; declare_id!(SWITCHBOARD_PROGRAM_ID); diff --git a/rust/switchboard-solana/src/macros.rs b/rust/switchboard-solana/src/macros.rs index f20a9b302..7f6c318f5 100644 --- a/rust/switchboard-solana/src/macros.rs +++ b/rust/switchboard-solana/src/macros.rs @@ -8,7 +8,7 @@ macro_rules! cfg_client { #[cfg_attr(doc_cfg, doc(cfg(not(target_os = "solana"))))] $item )* - } + }; } /// Macro used to include code only if the target_os is 'solana'. @@ -21,7 +21,7 @@ macro_rules! cfg_program { #[cfg_attr(doc_cfg, doc(cfg(target_os = "solana")))] $item )* - } + }; } /// Macro used to include code if the feature 'secrets' is enabled. @@ -30,11 +30,33 @@ macro_rules! cfg_program { macro_rules! cfg_secrets { ($($item:item)*) => { $( - #[cfg(not(target_os = "solana"))] - #[cfg(feature = "secrets")] - #[cfg_attr(doc_cfg, doc(cfg(not(target_os = "solana"))))] - #[cfg_attr(doc_cfg, doc(cfg(feature = "secrets")))] + #[cfg(all(feature = "secrets", not(target_os = "solana")))] + #[cfg_attr(doc_cfg, doc(cfg(feature = "secrets", not(target_os = "solana"))))] + $item + )* + }; +} + +/// Macro used to include code if the feature 'macros' is enabled. +#[macro_export] +macro_rules! cfg_macros { + ($($item:item)*) => { + $( + #[cfg(all(feature = "macros", not(target_os = "solana")))] + #[cfg_attr(doc_cfg, doc(cfg(feature = "macros", not(target_os = "solana"))))] + $item + )* + }; +} + +/// Macro used to include IPFS code if the feature 'ipfs' is enabled. +#[macro_export] +macro_rules! cfg_ipfs { + ($($item:item)*) => { + $( + #[cfg(all(feature = "ipfs", not(target_os = "solana")))] + #[cfg_attr(doc_cfg, doc(cfg(feature = "ipfs", not(target_os = "solana"))))] $item )* - } + }; } diff --git a/rust/switchboard-solana/src/oracle_program/accounts/aggregator.rs b/rust/switchboard-solana/src/oracle_program/accounts/aggregator.rs index 358d68bdd..3a080e544 100644 --- a/rust/switchboard-solana/src/oracle_program/accounts/aggregator.rs +++ b/rust/switchboard-solana/src/oracle_program/accounts/aggregator.rs @@ -276,7 +276,7 @@ impl AggregatorAccountData { Ok(()) } - pub fn is_expired(&self) -> Result { + pub fn is_expired(&self) -> anchor_lang::Result { if self.expiration == 0 { return Ok(false); } @@ -284,11 +284,25 @@ impl AggregatorAccountData { } cfg_client! { - pub async fn fetch( + pub fn fetch( client: &solana_client::rpc_client::RpcClient, pubkey: Pubkey, - ) -> std::result::Result { - crate::client::load_account(client, pubkey).await + ) -> std::result::Result { + crate::client::fetch_zerocopy_account(client, pubkey) + } + + pub async fn fetch_async( + client: &solana_client::nonblocking::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_async(client, pubkey).await + } + + pub fn fetch_sync( + client: &T, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_sync(client, pubkey) } } } diff --git a/rust/switchboard-solana/src/oracle_program/accounts/aggregator1.rs b/rust/switchboard-solana/src/oracle_program/accounts/aggregator1.rs new file mode 100644 index 000000000..e585b060f --- /dev/null +++ b/rust/switchboard-solana/src/oracle_program/accounts/aggregator1.rs @@ -0,0 +1,132 @@ +#[zero_copy(unsafe)] +#[repr(packed)] +#[derive(Default, Debug, PartialEq, Eq)] +pub struct Hash { + /// The bytes used to derive the hash. + pub data: [u8; 32], +} + +#[zero_copy(unsafe)] +#[repr(packed)] +#[derive(Default, PartialEq, Eq)] +pub struct AggregatorRound { + /// Maintains the number of successful responses received from nodes. + /// Nodes can submit one successful response per round. + pub num_success: u32, + /// Number of error responses. + pub num_error: u32, + /// Whether an update request round has ended. + pub is_closed: bool, + /// Maintains the `solana_program::clock::Slot` that the round was opened at. + pub round_open_slot: u64, + /// Maintains the `solana_program::clock::UnixTimestamp;` the round was opened at. + pub round_open_timestamp: i64, + /// Maintains the current median of all successful round responses. + pub result: SwitchboardDecimal, + /// Standard deviation of the accepted results in the round. + pub std_deviation: SwitchboardDecimal, + /// Maintains the minimum node response this round. + pub min_response: SwitchboardDecimal, + /// Maintains the maximum node response this round. + pub max_response: SwitchboardDecimal, + /// Pubkeys of the oracles fulfilling this round. + pub oracle_pubkeys_data: [Pubkey; 16], + /// Represents all successful node responses this round. `NaN` if empty. + pub medians_data: [SwitchboardDecimal; 16], + /// Current rewards/slashes oracles have received this round. + pub current_payout: [i64; 16], + /// Keep track of which responses are fulfilled here. + pub medians_fulfilled: [bool; 16], + /// Keeps track of which errors are fulfilled here. + pub errors_fulfilled: [bool; 16], +} + +#[derive(Copy, Clone, Debug, AnchorSerialize, AnchorDeserialize, Eq, PartialEq)] +#[repr(u8)] +pub enum AggregatorResolutionMode { + ModeRoundResolution = 0, + ModeSlidingResolution = 1, +} + +// #[zero_copy(unsafe)] +#[account(zero_copy(unsafe))] +#[repr(packed)] +#[derive(PartialEq)] +pub struct AggregatorAccountData { + /// Name of the aggregator to store on-chain. + pub name: [u8; 32], + /// Metadata of the aggregator to store on-chain. + pub metadata: [u8; 128], + /// Reserved. + pub _reserved1: [u8; 32], + /// Pubkey of the queue the aggregator belongs to. + pub queue_pubkey: Pubkey, + /// CONFIGS + /// Number of oracles assigned to an update request. + pub oracle_request_batch_size: u32, + /// Minimum number of oracle responses required before a round is validated. + pub min_oracle_results: u32, + /// Minimum number of job results before an oracle accepts a result. + pub min_job_results: u32, + /// Minimum number of seconds required between aggregator rounds. + pub min_update_delay_seconds: u32, + /// Unix timestamp for which no feed update will occur before. + pub start_after: i64, + /// Change percentage required between a previous round and the current round. If variance percentage is not met, reject new oracle responses. + pub variance_threshold: SwitchboardDecimal, + /// Number of seconds for which, even if the variance threshold is not passed, accept new responses from oracles. + pub force_report_period: i64, + /// Timestamp when the feed is no longer needed. + pub expiration: i64, + // + /// Counter for the number of consecutive failures before a feed is removed from a queue. If set to 0, failed feeds will remain on the queue. + pub consecutive_failure_count: u64, + /// Timestamp when the next update request will be available. + pub next_allowed_update_time: i64, + /// Flag for whether an aggregators configuration is locked for editing. + pub is_locked: bool, + /// Optional, public key of the crank the aggregator is currently using. Event based feeds do not need a crank. + pub crank_pubkey: Pubkey, + /// Latest confirmed update request result that has been accepted as valid. + pub latest_confirmed_round: AggregatorRound, + /// Oracle results from the current round of update request that has not been accepted as valid yet. + pub current_round: AggregatorRound, + /// List of public keys containing the job definitions for how data is sourced off-chain by oracles. + pub job_pubkeys_data: [Pubkey; 16], + /// Used to protect against malicious RPC nodes providing incorrect task definitions to oracles before fulfillment. + pub job_hashes: [Hash; 16], + /// Number of jobs assigned to an oracle. + pub job_pubkeys_size: u32, + /// Used to protect against malicious RPC nodes providing incorrect task definitions to oracles before fulfillment. + pub jobs_checksum: [u8; 32], + // + /// The account delegated as the authority for making account changes. + pub authority: Pubkey, + /// Optional, public key of a history buffer account storing the last N accepted results and their timestamps. + pub history_buffer: Pubkey, + /// The previous confirmed round result. + pub previous_confirmed_round_result: SwitchboardDecimal, + /// The slot when the previous confirmed round was opened. + pub previous_confirmed_round_slot: u64, + /// Whether an aggregator is permitted to join a crank. + pub disable_crank: bool, + /// Job weights used for the weighted median of the aggregator's assigned job accounts. + pub job_weights: [u8; 16], + /// Unix timestamp when the feed was created. + pub creation_timestamp: i64, + /// Use sliding windoe or round based resolution + /// NOTE: This changes result propogation in latest_round_result + pub resolution_mode: AggregatorResolutionMode, + /// Reserved for future info. + pub _ebuf: [u8; 138], +} + +impl Discriminator for FunctionRequestAccountData { + const DISCRIMINATOR: [u8; 8] = [217, 230, 65, 101, 201, 162, 27, 125]; +} + +impl Owner for FunctionRequestAccountData { + fn owner() -> Pubkey { + SWITCHBOARD_ATTESTATION_PROGRAM_ID + } +} diff --git a/rust/switchboard-solana/src/oracle_program/accounts/oracle.rs b/rust/switchboard-solana/src/oracle_program/accounts/oracle.rs index a5e9488e5..7c08c4af8 100644 --- a/rust/switchboard-solana/src/oracle_program/accounts/oracle.rs +++ b/rust/switchboard-solana/src/oracle_program/accounts/oracle.rs @@ -127,11 +127,25 @@ impl OracleAccountData { } cfg_client! { - pub async fn fetch( + pub fn fetch( client: &solana_client::rpc_client::RpcClient, pubkey: Pubkey, - ) -> std::result::Result { - crate::client::load_account(client, pubkey).await + ) -> std::result::Result { + crate::client::fetch_zerocopy_account(client, pubkey) + } + + pub async fn fetch_async( + client: &solana_client::nonblocking::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_async(client, pubkey).await + } + + pub fn fetch_sync( + client: &T, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_sync(client, pubkey) } } } diff --git a/rust/switchboard-solana/src/oracle_program/accounts/queue.rs b/rust/switchboard-solana/src/oracle_program/accounts/queue.rs index 8a7599124..0cbc3f4e4 100644 --- a/rust/switchboard-solana/src/oracle_program/accounts/queue.rs +++ b/rust/switchboard-solana/src/oracle_program/accounts/queue.rs @@ -156,12 +156,25 @@ impl OracleQueueAccountData { } cfg_client! { - pub async fn fetch( + pub fn fetch( client: &solana_client::rpc_client::RpcClient, pubkey: Pubkey, - ) -> std::result::Result { - crate::client::load_account(client, pubkey).await + ) -> std::result::Result { + crate::client::fetch_zerocopy_account(client, pubkey) } + pub async fn fetch_async( + client: &solana_client::nonblocking::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_async(client, pubkey).await + } + + pub fn fetch_sync( + client: &T, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_sync(client, pubkey) + } } } diff --git a/rust/switchboard-solana/src/oracle_program/accounts/vrf.rs b/rust/switchboard-solana/src/oracle_program/accounts/vrf.rs index e243e0db6..945fc1f5e 100644 --- a/rust/switchboard-solana/src/oracle_program/accounts/vrf.rs +++ b/rust/switchboard-solana/src/oracle_program/accounts/vrf.rs @@ -127,11 +127,25 @@ impl VrfAccountData { } cfg_client! { - pub async fn fetch( + pub fn fetch( client: &solana_client::rpc_client::RpcClient, pubkey: Pubkey, - ) -> std::result::Result { - crate::client::load_account(client, pubkey).await + ) -> std::result::Result { + crate::client::fetch_zerocopy_account(client, pubkey) + } + + pub async fn fetch_async( + client: &solana_client::nonblocking::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_async(client, pubkey).await + } + + pub fn fetch_sync( + client: &T, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_sync(client, pubkey) } } } diff --git a/rust/switchboard-solana/src/oracle_program/accounts/vrf_lite.rs b/rust/switchboard-solana/src/oracle_program/accounts/vrf_lite.rs index 53c732e9c..147cc177f 100644 --- a/rust/switchboard-solana/src/oracle_program/accounts/vrf_lite.rs +++ b/rust/switchboard-solana/src/oracle_program/accounts/vrf_lite.rs @@ -138,11 +138,25 @@ impl VrfLiteAccountData { } cfg_client! { - pub async fn fetch( + pub fn fetch( client: &solana_client::rpc_client::RpcClient, pubkey: Pubkey, - ) -> std::result::Result { - crate::client::load_account(client, pubkey).await + ) -> std::result::Result { + crate::client::fetch_zerocopy_account(client, pubkey) + } + + pub async fn fetch_async( + client: &solana_client::nonblocking::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_async(client, pubkey).await + } + + pub fn fetch_sync( + client: &T, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_sync(client, pubkey) } } } diff --git a/rust/switchboard-solana/src/oracle_program/accounts/vrf_pool.rs b/rust/switchboard-solana/src/oracle_program/accounts/vrf_pool.rs index eea82990a..a60c8c631 100644 --- a/rust/switchboard-solana/src/oracle_program/accounts/vrf_pool.rs +++ b/rust/switchboard-solana/src/oracle_program/accounts/vrf_pool.rs @@ -100,11 +100,25 @@ impl VrfPoolAccountData { } cfg_client! { - pub async fn fetch( + pub fn fetch( client: &solana_client::rpc_client::RpcClient, pubkey: Pubkey, - ) -> std::result::Result { - crate::client::load_account(client, pubkey).await + ) -> std::result::Result { + crate::client::fetch_zerocopy_account(client, pubkey) + } + + pub async fn fetch_async( + client: &solana_client::nonblocking::rpc_client::RpcClient, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_async(client, pubkey).await + } + + pub fn fetch_sync( + client: &T, + pubkey: Pubkey, + ) -> std::result::Result { + crate::client::fetch_zerocopy_account_sync(client, pubkey) } } } diff --git a/rust/switchboard-solana/src/prelude.rs b/rust/switchboard-solana/src/prelude.rs index 671a53b25..12b0c2ceb 100644 --- a/rust/switchboard-solana/src/prelude.rs +++ b/rust/switchboard-solana/src/prelude.rs @@ -1,15 +1,20 @@ -use crate::{cfg_client, cfg_program}; +use crate::{cfg_client, cfg_macros, cfg_program}; pub use crate::accounts::*; pub use crate::decimal::*; pub use crate::error::*; +pub use crate::events::*; pub use crate::instructions::*; pub use crate::seeds::*; pub use crate::types::*; pub use crate::{SWITCHBOARD_ATTESTATION_PROGRAM_ID, SWITCHBOARD_PROGRAM_ID}; -pub use switchboard_common::FunctionResult; +pub use switchboard_common::{ + unix_timestamp, ChainResultInfo, FunctionResult, FunctionResultV0, FunctionResultV1, + LegacyChainResultInfo, LegacySolanaFunctionResult, SolanaFunctionRequestType, + SolanaFunctionResult, SolanaFunctionResultV0, SolanaFunctionResultV1, FUNCTION_RESULT_PREFIX, +}; pub use anchor_spl; @@ -18,7 +23,7 @@ pub use rust_decimal; cfg_client! { pub use crate::client::*; - pub use switchboard_common::Gramine; + pub use switchboard_common::{ Gramine, SbFunctionError, SbError }; pub use anchor_client; pub use anchor_client::anchor_lang; @@ -27,9 +32,16 @@ cfg_client! { pub use anchor_client::anchor_lang::solana_program; pub use anchor_client::Cluster; - pub use solana_sdk::signer::keypair::{keypair_from_seed, Keypair}; + pub use solana_sdk::signer::keypair::{ keypair_from_seed, Keypair }; + pub use solana_sdk::transaction::Transaction; + pub use solana_sdk::message::Message; + + pub use solana_account_decoder; pub use anchor_lang::prelude::*; + + // Override anchor error + pub use std::result::Result; } cfg_program! { @@ -37,15 +49,26 @@ cfg_program! { pub use anchor_lang::solana_program; pub use anchor_lang::prelude::*; + + pub use anchor_lang::prelude::Result; +} + +cfg_macros! { + // Futures crate is needed by the proc_macro + pub use futures; + pub use futures::Future; + pub use switchboard_solana_macros::switchboard_function; + pub use switchboard_solana_macros::sb_error; } -pub use anchor_lang::prelude::*; pub use anchor_lang::{ AccountDeserialize, AccountSerialize, AnchorDeserialize, AnchorSerialize, Discriminator, InstructionData, Owner, ZeroCopy, }; + pub use anchor_spl::associated_token::AssociatedToken; +pub use anchor_spl::token::spl_token::native_mint as NativeMint; pub use anchor_spl::token::{Mint, Token, TokenAccount}; pub use solana_program::entrypoint::ProgramResult; -pub use solana_program::instruction::Instruction; +pub use solana_program::instruction::{AccountMeta, Instruction}; pub use solana_program::program::{invoke, invoke_signed}; diff --git a/rust/switchboard-solana/src/program_id.rs b/rust/switchboard-solana/src/program_id.rs new file mode 100644 index 000000000..eddb501b6 --- /dev/null +++ b/rust/switchboard-solana/src/program_id.rs @@ -0,0 +1,12 @@ +use crate::*; +// pub use anchor_lang::*; +// pub use anchor_lang::prelude::*; + +/// Program id for the Switchboard oracle program +/// SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f +pub const SWITCHBOARD_PROGRAM_ID: Pubkey = pubkey!("SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f"); + +/// Program id for the Switchboard oracle program +/// sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx +pub const SWITCHBOARD_ATTESTATION_PROGRAM_ID: Pubkey = + pubkey!("sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx"); diff --git a/rust/switchboard-solana/src/secrets.rs b/rust/switchboard-solana/src/secrets.rs index 342e600c9..81fcda89f 100644 --- a/rust/switchboard-solana/src/secrets.rs +++ b/rust/switchboard-solana/src/secrets.rs @@ -1,11 +1,11 @@ use crate::*; use rand::rngs::OsRng; -use serde_json::{json}; -use std::collections::HashMap; -use serde_json; +use rsa::{pkcs8::ToPublicKey, PaddingScheme, RsaPrivateKey, RsaPublicKey}; use serde::Deserialize; +use serde_json; +use serde_json::json; +use std::collections::HashMap; use std::result::Result; -use rsa::{RsaPrivateKey, RsaPublicKey, PaddingScheme, pkcs8::ToPublicKey}; #[allow(dead_code)] #[allow(non_snake_case)] @@ -29,30 +29,32 @@ pub struct Secrets { /// /// # Returns /// - `Map`: The key-value store of your secrets. -pub async fn fetch_secrets(url: &str) -> Result { +pub async fn fetch_secrets(url: &str) -> Result { let mut os_rng = OsRng::default(); - let priv_key = RsaPrivateKey::new(&mut os_rng, 2048) - .map_err(|_| SwitchboardClientError::KeyParseError)?; - let pub_key = RsaPublicKey::from(&priv_key).to_public_key_der() - .map_err(|_| SwitchboardClientError::KeyParseError)?; + let priv_key = RsaPrivateKey::new(&mut os_rng, 2048).map_err(|_| SbError::KeyParseError)?; + let pub_key = RsaPublicKey::from(&priv_key) + .to_public_key_der() + .map_err(|_| SbError::KeyParseError)?; let pub_key: &[u8] = pub_key.as_ref(); - let secrets_quote = Gramine::generate_quote(pub_key) - .map_err(|_| SwitchboardClientError::SgxError)?; + let secrets_quote = Gramine::generate_quote(pub_key).map_err(|_| SbError::SgxError)?; let client = reqwest::Client::new(); - let res = client.post(url) + let res = client + .post(url) .json(&json!({ "quote": &secrets_quote, "pubkey": pub_key, })) .send() .await - .map_err(|_| SwitchboardClientError::NetworkError)?; - let ciphertext = res.bytes().await.map_err(|_| SwitchboardClientError::NetworkError)?; + .map_err(|_| SbError::NetworkError)?; + let ciphertext = res.bytes().await.map_err(|_| SbError::NetworkError)?; let secrets: Secrets; let padding = PaddingScheme::new_pkcs1v15_encrypt(); secrets = serde_json::from_slice( - &priv_key.decrypt(padding, &ciphertext).map_err(|_| SwitchboardClientError::DecryptError)? - ).map_err(|_| SwitchboardClientError::ParseError)?; + &priv_key + .decrypt(padding, &ciphertext) + .map_err(|_| SbError::DecryptError)?, + ) + .map_err(|_| SbError::ParseError)?; Ok(secrets) } - diff --git a/rust/switchboard-solana/src/types.rs b/rust/switchboard-solana/src/types.rs index cc3d2c34d..ef1ed3282 100644 --- a/rust/switchboard-solana/src/types.rs +++ b/rust/switchboard-solana/src/types.rs @@ -12,13 +12,24 @@ pub use crate::oracle_program::{ }; pub use crate::attestation_program::{ - FunctionCloseParams, FunctionInitParams, FunctionRequestCloseParams, FunctionRequestInitParams, - FunctionRequestSetConfigParams, FunctionRequestTriggerRound, FunctionRequestVerifyParams, + AttestationPermissionInitParams, AttestationPermissionSetParams, + AttestationQueueAddMrEnclaveParams, AttestationQueueInitParams, FunctionCloseParams, + FunctionInitParams, FunctionRequestCloseParams, FunctionRequestInitAndTriggerParams, + FunctionRequestInitParams, FunctionRequestSetConfigParams, FunctionRequestTriggerRound, + FunctionRequestVerifyParams, FunctionRoutineInitParams, FunctionRoutineVerifyParams, FunctionSetEscrowParams, FunctionStatus, FunctionTriggerParams, FunctionVerifyParams, - MrEnclave, Quote, RequestStatus, SwitchboardAttestationPermission, VerificationStatus, - WalletFundParams, WalletInitParams, WalletWithdrawParams, + MrEnclave, Quote, RequestStatus, ResourceLevel, SwitchboardAttestationPermission, + VerificationStatus, VerifierQuoteVerifyParams, WalletFundParams, WalletInitParams, + WalletWithdrawParams, }; cfg_client! { - pub use crate::client::function_runner::FunctionVerifyAccounts; + pub use crate::attestation_program::{ + AttestationPermissionInitAccounts, AttestationPermissionSetAccounts, + FunctionRequestInitAndTriggerAccounts, FunctionRequestVerifyAccounts, + FunctionRoutineVerifyAccounts, FunctionVerifyAccounts, + SwitchboardWalletInitAccounts, VerifierHeartbeatAccounts, VerifierHeartbeatArgs, + VerifierInitAccounts, VerifierQuoteRotateAccounts, VerifierQuoteVerifyAccounts, + VerifierQuoteVerifyArgs, + }; } diff --git a/rust/switchboard-solana/src/utils.rs b/rust/switchboard-solana/src/utils.rs index 080fee229..f22241566 100644 --- a/rust/switchboard-solana/src/utils.rs +++ b/rust/switchboard-solana/src/utils.rs @@ -8,7 +8,7 @@ pub fn transfer<'a>( authority: &AccountInfo<'a>, auth_seed: &[&[&[u8]]], amount: u64, -) -> Result<()> { +) -> anchor_lang::Result<()> { if amount == 0 { return Ok(()); } @@ -30,7 +30,7 @@ pub fn wrap_native<'a>( payer: &AccountInfo<'a>, auth_seed: &[&[&[u8]]], amount: u64, -) -> Result<()> { +) -> anchor_lang::Result<()> { if amount == 0 { return Ok(()); } @@ -77,3 +77,15 @@ pub fn get_ixn_discriminator(ixn_name: &str) -> [u8; 8] { ); sighash } + +pub fn build_ix( + program_id: &Pubkey, + accounts: &A, + params: &I, +) -> Instruction { + Instruction { + program_id: *program_id, + accounts: accounts.to_account_metas(None), + data: params.data(), + } +}