diff --git a/Anchor.toml b/Anchor.toml index 0d0bd8a..0234984 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -1,27 +1,27 @@ anchor_version = "0.26.0" -solana_version = "1.13.5" +solana_version = "1.13.8" [features] seeds = true skip-lint = false [programs.localnet] -gpl_core = "CDDMdCAWB5AXgvEy7XJRggAu37QPG1b9aJXndZoPUkkm" +gpl_core = "6MhUAJtKdJx3RDCffUsJsQm8xy9YhhywjEmMYrxRc5j6" gpl_compression = "41kNwkQ9jESNYZJyAA1ENscQfx7vfkEf6uetVSFmfyaW" gpl_session = "3ao63wcSRNa76bncC2M3KupNtXBFiDyNbgK52VG7dLaE" -gpl_nameservice = "7LEuQxAEegasvBSq7dDrMregc3mrDtTyHiytNK9pU68u" +gpl_nameservice = "5kWEYrdyryq3jGP5sUcKwTySzxr3dHzWFBVA3vkt6Nj5" [programs.devnet] -gpl_core = "CDDMdCAWB5AXgvEy7XJRggAu37QPG1b9aJXndZoPUkkm" +gpl_core = "6MhUAJtKdJx3RDCffUsJsQm8xy9YhhywjEmMYrxRc5j6" gpl_compression = "41kNwkQ9jESNYZJyAA1ENscQfx7vfkEf6uetVSFmfyaW" gpl_session = "3ao63wcSRNa76bncC2M3KupNtXBFiDyNbgK52VG7dLaE" -gpl_nameservice = "7LEuQxAEegasvBSq7dDrMregc3mrDtTyHiytNK9pU68u" +gpl_nameservice = "5kWEYrdyryq3jGP5sUcKwTySzxr3dHzWFBVA3vkt6Nj5" [programs.mainnet] -gpl_core = "CDDMdCAWB5AXgvEy7XJRggAu37QPG1b9aJXndZoPUkkm" +gpl_core = "6MhUAJtKdJx3RDCffUsJsQm8xy9YhhywjEmMYrxRc5j6" gpl_compression = "41kNwkQ9jESNYZJyAA1ENscQfx7vfkEf6uetVSFmfyaW" gpl_session = "3ao63wcSRNa76bncC2M3KupNtXBFiDyNbgK52VG7dLaE" -gpl_nameservice = "7LEuQxAEegasvBSq7dDrMregc3mrDtTyHiytNK9pU68u" +gpl_nameservice = "5kWEYrdyryq3jGP5sUcKwTySzxr3dHzWFBVA3vkt6Nj5" [[test.genesis]] diff --git a/Cargo.lock b/Cargo.lock index 486d4b7..4689d77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,16 +8,16 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.8", + "getrandom 0.2.9", "once_cell", "version_check", ] [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] @@ -33,7 +33,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn", + "syn 1.0.109", ] [[package]] @@ -48,7 +48,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 1.0.109", ] [[package]] @@ -59,7 +59,7 @@ checksum = "e1be64a48e395fe00b8217287f226078be2cf32dae42fdf8a885b997945c3d28" dependencies = [ "anchor-syn", "proc-macro2", - "syn", + "syn 1.0.109", ] [[package]] @@ -71,7 +71,7 @@ dependencies = [ "anchor-syn", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -84,7 +84,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -95,10 +95,10 @@ checksum = "c6700a6f5c888a9c33fe8afc0c64fd8575fa28d05446037306d0f96102ae4480" dependencies = [ "anchor-syn", "anyhow", - "heck 0.3.3", + "heck", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -111,7 +111,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -124,7 +124,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -137,7 +137,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -172,28 +172,119 @@ checksum = "0418bcb5daac3b8cb1b60d8fdb1d468ca36f5509f31fb51179326fae1028fdcc" dependencies = [ "anyhow", "bs58 0.3.1", - "heck 0.3.3", + "heck", "proc-macro2", "proc-macro2-diagnostics", "quote", "serde", "serde_json", "sha2 0.9.9", - "syn", + "syn 1.0.109", "thiserror", ] [[package]] name = "anyhow" -version = "1.0.66" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + +[[package]] +name = "ark-bn254" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea691771ebbb28aea556c044e2e5c5227398d840cee0c34d4d20fa8eb2689e8c" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea978406c4b1ca13c2db2373b05cc55429c3575b8b21f1b9ee859aa5b03dd42" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std", + "digest 0.9.0", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +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.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] name = "arrayvec" @@ -269,9 +360,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] @@ -302,7 +393,7 @@ dependencies = [ "borsh-schema-derive-internal", "proc-macro-crate", "proc-macro2", - "syn", + "syn 1.0.109", ] [[package]] @@ -313,7 +404,7 @@ checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -324,7 +415,7 @@ checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -341,9 +432,9 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" [[package]] name = "bv" @@ -357,22 +448,22 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.12.3" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe233b960f12f8007e3db2d136e3cb1c291bfd7396e384ee76025fc1a3932b4" +checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -383,9 +474,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cc" -version = "1.0.77" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" dependencies = [ "jobserver", ] @@ -408,9 +499,9 @@ dependencies = [ [[package]] name = "console_log" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501a375961cef1a0d44767200e66e4a559283097e91d0730b1d75dfb2f8a1494" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" dependencies = [ "log", "web-sys", @@ -418,24 +509,24 @@ dependencies = [ [[package]] name = "constant_time_eq" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3ad85c1f65dc7b37604eb0e89748faf0b9653065f2a8ef69f96a687ec1e9279" +checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] [[package]] name = "crossbeam-channel" -version = "0.5.6" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ "cfg-if", "crossbeam-utils", @@ -443,9 +534,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -454,22 +545,22 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.7.1", + "memoffset", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if", ] @@ -514,6 +605,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "digest" version = "0.9.0" @@ -529,16 +631,16 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", "crypto-common", "subtle", ] [[package]] name = "either" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "feature-probe" @@ -548,9 +650,9 @@ checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "serde", "typenum", @@ -572,9 +674,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if", "js-sys", @@ -598,10 +700,9 @@ name = "gpl-core" version = "1.0.0" dependencies = [ "anchor-lang", + "gpl-nameservice", "gpl-session", "solana-security-txt", - "strum", - "strum_macros", ] [[package]] @@ -633,7 +734,7 @@ version = "0.1.0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -663,17 +764,11 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "heck" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" - [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" dependencies = [ "libc", ] @@ -726,24 +821,24 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "jobserver" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" dependencies = [ "wasm-bindgen", ] @@ -765,9 +860,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "libsecp256k1" @@ -782,7 +877,7 @@ dependencies = [ "libsecp256k1-core", "libsecp256k1-gen-ecmult", "libsecp256k1-gen-genmult", - "rand", + "rand 0.7.3", "serde", "sha2 0.9.9", "typenum", @@ -844,29 +939,31 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] [[package]] -name = "memoffset" -version = "0.7.1" +name = "num-bigint" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ "autocfg", + "num-integer", + "num-traits", ] [[package]] @@ -877,7 +974,17 @@ checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", +] + +[[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]] @@ -891,9 +998,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ "hermit-abi", "libc", @@ -901,9 +1008,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "opaque-debug" @@ -923,9 +1030,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.5" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", @@ -934,6 +1041,12 @@ dependencies = [ "windows-sys", ] +[[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" @@ -943,6 +1056,16 @@ dependencies = [ "crypto-mac", ] +[[package]] +name = "pest" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e68e84bfb01f0507134eac1e9b410a12ba379d064eab48c50ba4ce329a527b70" +dependencies = [ + "thiserror", + "ucd-trie", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -960,9 +1083,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] @@ -975,16 +1098,16 @@ checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", "yansi", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -997,11 +1120,21 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "getrandom 0.1.16", "libc", - "rand_chacha", + "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 = [ + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -1012,6 +1145,16 @@ dependencies = [ "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" @@ -1027,7 +1170,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.8", + "getrandom 0.2.9", ] [[package]] @@ -1050,20 +1193,19 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e060280438193c554f654141c9ea9417886713b7acd75974c85b18a69a88e0b" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" dependencies = [ - "crossbeam-deque", "either", "rayon-core", ] [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -1082,9 +1224,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ "aho-corasick", "memchr", @@ -1093,9 +1235,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "rustc-hash" @@ -1103,26 +1245,35 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver", + "semver 1.0.17", ] [[package]] name = "rustversion" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "scopeguard" @@ -1132,44 +1283,62 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "semver" -version = "1.0.14" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] [[package]] name = "serde" -version = "1.0.149" +version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055" +checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.7" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.149" +version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4" +checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ "itoa", "ryu", @@ -1202,9 +1371,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +checksum = "54c2bb1a323307527314a36bfb73f24febb08ce2b8a554bf4ffd6f51ad15198c" dependencies = [ "digest 0.10.6", "keccak", @@ -1228,9 +1397,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "solana-frozen-abi" -version = "1.14.12" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c39813ee5b249cb8ccb325d3639323eb3616e7bb9a2b1502936d7ea20530097" +checksum = "48f7051cccdf891ac2603cdd295eb651529fe2b678b6b3af60b82dec9a9b3b06" dependencies = [ "ahash", "blake3", @@ -1249,7 +1418,7 @@ dependencies = [ "memmap2", "once_cell", "rand_core 0.6.4", - "rustc_version", + "rustc_version 0.4.0", "serde", "serde_bytes", "serde_derive", @@ -1262,22 +1431,26 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.14.12" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad43ac27c4b8d7a3ce0e2cb8642a7e3b8ea5e3c29ecea38045a8518519adccf" +checksum = "06395428329810ade1d2518a7e75d8a6f02d01fe548aabb60ff1ba6a2eaebbe5" dependencies = [ "proc-macro2", "quote", - "rustc_version", - "syn", + "rustc_version 0.4.0", + "syn 1.0.109", ] [[package]] name = "solana-program" -version = "1.14.12" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dafff676128fe508ab83147b6fb19534fc33f43ec14789da1f1867e9ea06887" +checksum = "1ae9f0fa7db3a4e90fa0df2723ac8cbc042e579cf109cd0380bc5a8c88bed924" dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "array-bytes", "base64 0.13.1", "bincode", "bitflags", @@ -1291,20 +1464,21 @@ dependencies = [ "console_error_panic_hook", "console_log", "curve25519-dalek", - "getrandom 0.2.8", + "getrandom 0.2.9", "itertools", "js-sys", "lazy_static", "libc", "libsecp256k1", "log", - "memoffset 0.6.5", + "memoffset", + "num-bigint", "num-derive", "num-traits", "parking_lot", - "rand", - "rand_chacha", - "rustc_version", + "rand 0.7.3", + "rand_chacha 0.2.2", + "rustc_version 0.4.0", "rustversion", "serde", "serde_bytes", @@ -1323,15 +1497,15 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.14.12" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f89a14a8f1e7708fe19ee3140125e9d8279945ead74cb09e65c94dd5cf0640c3" +checksum = "f809319358d5da7c3a0ac08ebf4d87b21170d928dbb7260254e8f3061f7f9e0e" dependencies = [ "bs58 0.4.0", "proc-macro2", "quote", "rustversion", - "syn", + "syn 1.0.109", ] [[package]] @@ -1342,9 +1516,9 @@ checksum = "7e0461f3afb29d8591300b3dd09b5472b3772d65688a2826ad960b8c0d5fa605" [[package]] name = "spl-account-compression" -version = "0.1.7" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b37557082d95b45e9ccbce25eec922a59895a9e408d2deb5113140f9fc970d0" +checksum = "f7a5417eae3c924553b872de5f1bca5945334a235f8d94841bd44c6dd7c6358c" dependencies = [ "anchor-lang", "bytemuck", @@ -1354,9 +1528,9 @@ dependencies = [ [[package]] name = "spl-concurrent-merkle-tree" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8518df14b19ada73c6bd15ee344de8ab720580fb2df0029342f9a772e2392d" +checksum = "26dd605d33bdc8d2522a9f55207c3eac06737b2e8310f602e252b510e3db1210" dependencies = [ "bytemuck", "solana-program", @@ -1372,25 +1546,6 @@ dependencies = [ "solana-program", ] -[[package]] -name = "strum" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" - -[[package]] -name = "strum_macros" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" -dependencies = [ - "heck 0.4.0", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - [[package]] name = "subtle" version = "2.4.1" @@ -1399,9 +1554,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.105" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -1409,35 +1564,34 @@ dependencies = [ ] [[package]] -name = "synstructure" -version = "0.12.6" +name = "syn" +version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" dependencies = [ "proc-macro2", "quote", - "syn", - "unicode-xid", + "unicode-ident", ] [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -1450,7 +1604,7 @@ dependencies = [ "hmac", "once_cell", "pbkdf2", - "rand", + "rand 0.7.3", "rustc-hash", "sha2 0.9.9", "thiserror", @@ -1470,15 +1624,15 @@ dependencies = [ [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "toml" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] @@ -1489,11 +1643,17 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "ucd-trie" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" + [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "unicode-normalization" @@ -1506,15 +1666,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" - -[[package]] -name = "unicode-xid" -version = "0.2.4" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "version_check" @@ -1536,9 +1690,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1546,24 +1700,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1571,28 +1725,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" [[package]] name = "web-sys" -version = "0.3.60" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" dependencies = [ "js-sys", "wasm-bindgen", @@ -1600,9 +1754,18 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -1615,45 +1778,45 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "yansi" @@ -1672,12 +1835,11 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.3.3" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn", - "synstructure", + "syn 2.0.15", ] diff --git a/package.json b/package.json index ad42be3..e883a45 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@project-serum/anchor": "^0.26.0" }, "devDependencies": { + "@faker-js/faker": "^7.6.0", "@solana/spl-account-compression": "^0.1.5", "@types/bn.js": "^5.1.0", "@types/chai": "^4.3.0", diff --git a/programs/gpl_compression/Cargo.toml b/programs/gpl_compression/Cargo.toml index a95bc24..00f561e 100644 --- a/programs/gpl_compression/Cargo.toml +++ b/programs/gpl_compression/Cargo.toml @@ -20,6 +20,6 @@ default = [] [dependencies] anchor-lang = "0.26.0" -gpl-core = { version = "1.0.0", path = "../gpl_core", features = ["cpi"] } +gpl-core = { version = "^1.0.0", path = "../gpl_core", features = ["cpi"] } solana-security-txt = "1.1.0" -spl-account-compression = {version = "0.1.7", features = ["cpi"]} +spl-account-compression = {version = "0.1.10", features = ["cpi"]} diff --git a/programs/gpl_compression/src/events.rs b/programs/gpl_compression/src/events.rs index b2cc187..e3d9df8 100644 --- a/programs/gpl_compression/src/events.rs +++ b/programs/gpl_compression/src/events.rs @@ -7,7 +7,6 @@ pub struct CompressedPostNew { pub post_bump: u8, pub index: u32, pub profile: Pubkey, - pub user: Pubkey, pub random_hash: [u8; 32], pub metadata_uri: String, pub timestamp: i64, @@ -20,7 +19,6 @@ pub struct CompressedPostUpdated { pub post_bump: u8, pub index: u32, pub profile: Pubkey, - pub user: Pubkey, pub random_hash: [u8; 32], pub metadata_uri: String, pub timestamp: i64, @@ -33,7 +31,6 @@ pub struct CompressedPostDeleted { pub post_bump: u8, pub index: u32, pub profile: Pubkey, - pub user: Pubkey, pub random_hash: [u8; 32], pub metadata_uri: String, pub timestamp: i64, @@ -47,7 +44,6 @@ pub struct CompressedConnectionNew { pub index: u32, pub from_profile: Pubkey, pub to_profile: Pubkey, - pub user: Pubkey, pub timestamp: i64, } @@ -59,7 +55,6 @@ pub struct CompressedConnectionDeleted { pub index: u32, pub from_profile: Pubkey, pub to_profile: Pubkey, - pub user: Pubkey, pub timestamp: i64, } @@ -71,7 +66,6 @@ pub struct CompressedReactionNew { pub index: u32, pub from_profile: Pubkey, pub to_post: Pubkey, - pub user: Pubkey, pub reaction_type: String, pub timestamp: i64, } @@ -84,7 +78,6 @@ pub struct CompressedReactionDeleted { pub index: u32, pub from_profile: Pubkey, pub to_post: Pubkey, - pub user: Pubkey, pub reaction_type: String, pub timestamp: i64, } @@ -97,7 +90,6 @@ pub struct CompressedCommentNew { pub index: u32, pub reply_to: Pubkey, pub profile: Pubkey, - pub user: Pubkey, pub random_hash: [u8; 32], pub metadata_uri: String, pub timestamp: i64, diff --git a/programs/gpl_compression/src/instructions/comment.rs b/programs/gpl_compression/src/instructions/comment.rs index 6698cc7..2fbc4f5 100644 --- a/programs/gpl_compression/src/instructions/comment.rs +++ b/programs/gpl_compression/src/instructions/comment.rs @@ -1,6 +1,6 @@ use std::convert::AsRef; -use gpl_core::state::{Post, Profile, User}; +use gpl_core::state::{Post, Profile}; use anchor_lang::prelude::*; use anchor_lang::solana_program::keccak::hashv; @@ -27,25 +27,13 @@ pub struct CreateCompressedComment<'info> { #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - from_profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), - ], - seeds::program = gpl_core_program.key(), - bump, - has_one = user, - )] - pub from_profile: Account<'info, Profile>, - - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), + from_profile.random_hash.as_ref(), ], seeds::program = gpl_core_program.key(), bump, has_one = authority, )] - pub user: Account<'info, User>, + pub from_profile: Account<'info, Profile>, #[account(seeds = [merkle_tree.key.as_ref()], bump)] pub tree_config: Account<'info, TreeConfig>, @@ -139,7 +127,6 @@ pub fn create_compressed_comment_handler<'info>( post_bump, reply_to, profile: *ctx.accounts.from_profile.to_account_info().key, - user: *ctx.accounts.user.to_account_info().key, random_hash: random_hash, metadata_uri: post.metadata_uri.clone(), timestamp: Clock::get()?.unix_timestamp, diff --git a/programs/gpl_compression/src/instructions/connection.rs b/programs/gpl_compression/src/instructions/connection.rs index f503b7f..418c687 100644 --- a/programs/gpl_compression/src/instructions/connection.rs +++ b/programs/gpl_compression/src/instructions/connection.rs @@ -6,7 +6,7 @@ use gpl_core::errors::ConnectionError; use spl_account_compression::wrap_application_data_v1; use spl_account_compression::Node; -use gpl_core::state::{Connection, Profile, User}; +use gpl_core::state::{Connection, Profile}; use anchor_lang::prelude::*; use std::convert::AsRef; @@ -24,34 +24,14 @@ pub struct CreateCompressedConnection<'info> { #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - from_profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), + from_profile.random_hash.as_ref(), ], seeds::program = gpl_core_program.key(), bump, - has_one = user, + has_one = authority, )] pub from_profile: Account<'info, Profile>, - #[account( - seeds = [ - PROFILE_PREFIX_SEED.as_bytes(), - to_profile.namespace.as_ref().as_bytes(), - to_profile.user.as_ref(), - ], - seeds::program = gpl_core_program.key(), - bump, - )] pub to_profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - seeds::program = gpl_core_program.key(), - bump, - has_one = authority, - )] - pub user: Account<'info, User>, #[account(seeds = [merkle_tree.key.as_ref()], bump)] pub tree_config: Account<'info, TreeConfig>, @@ -128,7 +108,6 @@ pub fn create_compressed_connection_handler( from_profile: *from_profile.to_account_info().key, to_profile: *to_profile.to_account_info().key, asset_id, - user: *ctx.accounts.user.to_account_info().key, timestamp: Clock::get()?.unix_timestamp, index: 0 // TODO: Get the index from the tree }); @@ -144,34 +123,14 @@ pub struct DeleteCompressedConnection<'info> { #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - from_profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), + from_profile.random_hash.as_ref(), ], seeds::program = gpl_core_program.key(), bump, - has_one = user, + has_one = authority, )] pub from_profile: Account<'info, Profile>, - #[account( - seeds = [ - PROFILE_PREFIX_SEED.as_bytes(), - to_profile.namespace.as_ref().as_bytes(), - to_profile.user.as_ref(), - ], - seeds::program = gpl_core_program.key(), - bump, - )] pub to_profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - seeds::program = gpl_core_program.key(), - bump, - has_one = authority, - )] - pub user: Account<'info, User>, #[account(seeds = [merkle_tree.key.as_ref()], bump)] pub tree_config: Account<'info, TreeConfig>, @@ -255,7 +214,6 @@ pub fn delete_compressed_connection_handler<'info>( from_profile: *from_profile.to_account_info().key, to_profile: *to_profile.to_account_info().key, asset_id, - user: *ctx.accounts.user.to_account_info().key, timestamp: Clock::get()?.unix_timestamp, index }); diff --git a/programs/gpl_compression/src/instructions/post.rs b/programs/gpl_compression/src/instructions/post.rs index c446cde..ab79ff5 100644 --- a/programs/gpl_compression/src/instructions/post.rs +++ b/programs/gpl_compression/src/instructions/post.rs @@ -7,7 +7,7 @@ use gpl_core::errors::PostError; use spl_account_compression::wrap_application_data_v1; use spl_account_compression::Node; -use gpl_core::state::{Post, Profile, User, MAX_LEN_URI}; +use gpl_core::state::{Post, Profile, MAX_LEN_URI}; use anchor_lang::prelude::*; use std::convert::AsRef; @@ -26,24 +26,13 @@ pub struct CreateCompressedPost<'info> { #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), - ], - seeds::program = gpl_core_program.key(), - bump, - has_one = user, - )] - pub profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), + profile.random_hash.as_ref(), ], seeds::program = gpl_core_program.key(), bump, has_one = authority, )] - pub user: Account<'info, User>, + pub profile: Account<'info, Profile>, #[account(seeds = [merkle_tree.key.as_ref()], bump)] pub tree_config: Account<'info, TreeConfig>, @@ -110,7 +99,6 @@ pub fn create_compressed_post_handler( post_id, post_bump, profile: *ctx.accounts.profile.to_account_info().key, - user: *ctx.accounts.user.to_account_info().key, random_hash: random_hash, metadata_uri: post.metadata_uri.clone(), timestamp: Clock::get()?.unix_timestamp, @@ -127,24 +115,13 @@ pub struct UpdateCompressedPost<'info> { #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), - ], - seeds::program = gpl_core_program.key(), - bump, - has_one = user, - )] - pub profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), + profile.random_hash.as_ref(), ], seeds::program = gpl_core_program.key(), bump, has_one = authority, )] - pub user: Account<'info, User>, + pub profile: Account<'info, Profile>, #[account(seeds = [merkle_tree.key.as_ref()], bump)] pub tree_config: Account<'info, TreeConfig>, @@ -236,7 +213,6 @@ pub fn update_compressed_post_handler<'info>( post_id, post_bump, profile: *ctx.accounts.profile.to_account_info().key, - user: *ctx.accounts.user.to_account_info().key, random_hash: random_hash, metadata_uri: new_post.metadata_uri.clone(), timestamp: Clock::get()?.unix_timestamp, @@ -254,24 +230,13 @@ pub struct DeleteCompressedPost<'info> { #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), - ], - seeds::program = gpl_core_program.key(), - bump, - has_one = user, - )] - pub profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), + profile.random_hash.as_ref(), ], seeds::program = gpl_core_program.key(), bump, has_one = authority, )] - pub user: Account<'info, User>, + pub profile: Account<'info, Profile>, #[account(seeds = [merkle_tree.key.as_ref()], bump)] pub tree_config: Account<'info, TreeConfig>, @@ -348,7 +313,6 @@ pub fn delete_compressed_post_handler<'info>( post_id, post_bump, profile: *ctx.accounts.profile.to_account_info().key, - user: *ctx.accounts.user.to_account_info().key, random_hash: random_hash, metadata_uri: old_post.metadata_uri.clone(), timestamp: Clock::get()?.unix_timestamp, diff --git a/programs/gpl_compression/src/instructions/reaction.rs b/programs/gpl_compression/src/instructions/reaction.rs index 6c7cd2f..5474d62 100644 --- a/programs/gpl_compression/src/instructions/reaction.rs +++ b/programs/gpl_compression/src/instructions/reaction.rs @@ -1,10 +1,7 @@ use anchor_lang::Discriminator; -use std::convert::AsRef; -use std::str::FromStr; +use gpl_core::state::Profile; use gpl_core::state::Reaction; -use gpl_core::state::ReactionType; -use gpl_core::state::{Profile, User}; use anchor_lang::prelude::*; use anchor_lang::solana_program::keccak::hashv; @@ -30,25 +27,13 @@ pub struct CreateCompressedReaction<'info> { #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - from_profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), - ], - seeds::program = gpl_core_program.key(), - bump, - has_one = user, - )] - pub from_profile: Account<'info, Profile>, - - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), + from_profile.random_hash.as_ref(), ], seeds::program = gpl_core_program.key(), bump, has_one = authority, )] - pub user: Account<'info, User>, + pub from_profile: Account<'info, Profile>, #[account(seeds = [merkle_tree.key.as_ref()], bump)] pub tree_config: Account<'info, TreeConfig>, @@ -82,6 +67,8 @@ pub fn create_compressed_reaction_handler<'info>( post_leaf: [u8; 32], post_index: u32, ) -> Result<()> { + Reaction::validate_reaction_type(&reaction_type)?; + let from_profile = &ctx.accounts.from_profile; // Check if the to_post exists @@ -101,7 +88,7 @@ pub fn create_compressed_reaction_handler<'info>( let reaction_seeds = [ REACTION_PREFIX_SEED.as_bytes(), - reaction_type.as_bytes(), + reaction_type.as_ref(), to_post.as_ref(), from_profile.to_account_info().key.as_ref(), ]; @@ -116,7 +103,7 @@ pub fn create_compressed_reaction_handler<'info>( let reaction = Reaction { from_profile: *from_profile.to_account_info().key, to_post, - reaction_type: ReactionType::from_str(&reaction_type).unwrap(), + reaction_type: reaction_type.clone(), }; let leaf = LeafSchema { @@ -143,12 +130,11 @@ pub fn create_compressed_reaction_handler<'info>( emit!(CompressedReactionNew { from_profile: *from_profile.to_account_info().key, to_post, - reaction_type: reaction_type.clone(), + reaction_type, reaction_id, reaction_bump, asset_id, index: 0, //TODO: get the index - user: *ctx.accounts.user.to_account_info().key, timestamp: Clock::get()?.unix_timestamp, }); @@ -162,25 +148,13 @@ pub struct DeleteCompressedReaction<'info> { #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - from_profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), - ], - seeds::program = gpl_core_program.key(), - bump, - has_one = user, - )] - pub from_profile: Account<'info, Profile>, - - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), + from_profile.random_hash.as_ref(), ], seeds::program = gpl_core_program.key(), bump, has_one = authority, )] - pub user: Account<'info, User>, + pub from_profile: Account<'info, Profile>, #[account(seeds = [merkle_tree.key.as_ref()], bump)] pub tree_config: Account<'info, TreeConfig>, @@ -206,10 +180,12 @@ pub fn delete_compressed_reaction_handler<'info>( root: [u8; 32], index: u32, ) -> Result<()> { + Reaction::validate_reaction_type(&reaction_type)?; + let from_profile = &ctx.accounts.from_profile; let reaction_seeds = [ REACTION_PREFIX_SEED.as_bytes(), - reaction_type.as_bytes(), + reaction_type.as_ref(), to_post.as_ref(), from_profile.to_account_info().key.as_ref(), ]; @@ -224,7 +200,7 @@ pub fn delete_compressed_reaction_handler<'info>( let old_reaction = Reaction { from_profile: *from_profile.to_account_info().key, to_post, - reaction_type: ReactionType::from_str(&reaction_type).unwrap(), + reaction_type: reaction_type.clone(), }; let old_leaf = LeafSchema { @@ -257,12 +233,11 @@ pub fn delete_compressed_reaction_handler<'info>( emit!(CompressedReactionDeleted { from_profile: *from_profile.to_account_info().key, to_post, - reaction_type: reaction_type.clone(), + reaction_type, reaction_id, reaction_bump, asset_id, index, - user: *ctx.accounts.user.to_account_info().key, timestamp: Clock::get()?.unix_timestamp, }); diff --git a/programs/gpl_core/Cargo.toml b/programs/gpl_core/Cargo.toml index 70f96af..5c69bbe 100644 --- a/programs/gpl_core/Cargo.toml +++ b/programs/gpl_core/Cargo.toml @@ -21,6 +21,5 @@ default = [] [dependencies] anchor-lang = { version = "0.26.0" } gpl-session = { version = "0.2.0", path = "../gpl_session", features = ["no-entrypoint"] } +gpl-nameservice = { version = "0.1.0", path = "../gpl_nameservice", features = ["no-entrypoint"] } solana-security-txt = "1.1.0" -strum = "0.24.1" -strum_macros = "0.24.3" diff --git a/programs/gpl_core/src/errors.rs b/programs/gpl_core/src/errors.rs index adadd6b..e6d4a82 100644 --- a/programs/gpl_core/src/errors.rs +++ b/programs/gpl_core/src/errors.rs @@ -2,7 +2,12 @@ use anchor_lang::prelude::*; #[error_code] pub enum GumError { + URITooLong, + CannotConnectToSelf, UnauthorizedSigner, + UnverifiedIssuer, + InvalidSignerToVerify, + ReactionTypeTooLong, } #[error_code] diff --git a/programs/gpl_core/src/events.rs b/programs/gpl_core/src/events.rs index b79893b..3914539 100644 --- a/programs/gpl_core/src/events.rs +++ b/programs/gpl_core/src/events.rs @@ -1,52 +1,32 @@ -use crate::state::{Namespace, ReactionType}; use anchor_lang::prelude::*; -// TODO: Explicitly add the signer to all events -// This would be useful to quickly find out who owns the current user account. Perhaps this can be -// looked up? Let's see how this works out. - -// This event is emitted whenever a new user is created. -#[event] -pub struct UserNew { - pub user: Pubkey, - pub random_hash: [u8; 32], - pub authority: Pubkey, - pub timestamp: i64, -} - -// This event is emitted whenever the user's authority is changed. -#[event] -pub struct UserAuthorityChanged { - pub user: Pubkey, - pub new_authority: Pubkey, - pub old_authority: Pubkey, - pub timestamp: i64, -} - -// This event is emitted whenever the user's account is deleted. +// This event is emitted whenever a new profile is created. #[event] -pub struct UserDeleted { - pub user: Pubkey, +pub struct ProfileNew { + pub profile: Pubkey, pub authority: Pubkey, + pub random_hash: [u8; 32], pub timestamp: i64, + pub screen_name: Pubkey, + pub metadata_uri: String, } -// This event is emitted whenever a new profile is created. +// This event is emitted whenever a profile is updated. #[event] -pub struct ProfileNew { +pub struct ProfileUpdated { pub profile: Pubkey, - pub user: Pubkey, - pub namespace: Namespace, pub timestamp: i64, + pub screen_name: Pubkey, + pub metadata_uri: String, } // This event is emitted whenever a profile is deleted. #[event] pub struct ProfileDeleted { pub profile: Pubkey, - pub user: Pubkey, - pub namespace: Namespace, pub timestamp: i64, + pub screen_name: Pubkey, + pub metadata_uri: String, } // This event is emitted whenever a new post is created. @@ -54,7 +34,6 @@ pub struct ProfileDeleted { pub struct PostNew { pub post: Pubkey, pub profile: Pubkey, - pub user: Pubkey, pub random_hash: [u8; 32], pub metadata_uri: String, pub timestamp: i64, @@ -65,7 +44,6 @@ pub struct PostNew { pub struct PostUpdated { pub post: Pubkey, pub profile: Pubkey, - pub user: Pubkey, pub metadata_uri: String, pub timestamp: i64, } @@ -75,7 +53,6 @@ pub struct PostUpdated { pub struct PostDeleted { pub post: Pubkey, pub profile: Pubkey, - pub user: Pubkey, pub timestamp: i64, } @@ -84,7 +61,6 @@ pub struct PostDeleted { pub struct PostCommentNew { pub post: Pubkey, pub profile: Pubkey, - pub user: Pubkey, pub random_hash: [u8; 32], pub metadata_uri: String, pub reply_to: Pubkey, @@ -95,7 +71,6 @@ pub struct PostCommentNew { #[event] pub struct ConnectionNew { pub connection: Pubkey, - pub user: Pubkey, pub from_profile: Pubkey, pub to_profile: Pubkey, pub timestamp: i64, @@ -105,7 +80,6 @@ pub struct ConnectionNew { #[event] pub struct ConnectionDeleted { pub connection: Pubkey, - pub user: Pubkey, pub from_profile: Pubkey, pub to_profile: Pubkey, pub timestamp: i64, @@ -115,8 +89,7 @@ pub struct ConnectionDeleted { #[event] pub struct ReactionNew { pub reaction: Pubkey, - pub reaction_type: ReactionType, - pub user: Pubkey, + pub reaction_type: String, pub from_profile: Pubkey, pub to_post: Pubkey, pub timestamp: i64, @@ -126,38 +99,8 @@ pub struct ReactionNew { #[event] pub struct ReactionDeleted { pub reaction: Pubkey, - pub reaction_type: ReactionType, - pub user: Pubkey, + pub reaction_type: String, pub from_profile: Pubkey, pub to_post: Pubkey, pub timestamp: i64, } - -// This event is emitted whenever a new profile metadata is created. -#[event] -pub struct ProfileMetadataNew { - pub profile_metadata: Pubkey, - pub profile: Pubkey, - pub user: Pubkey, - pub metadata_uri: String, - pub timestamp: i64, -} - -// This event is emitted whenever a profile metadata is updated. -#[event] -pub struct ProfileMetadataUpdated { - pub profile_metadata: Pubkey, - pub profile: Pubkey, - pub user: Pubkey, - pub metadata_uri: String, - pub timestamp: i64, -} - -// This event is emitted whenever a profile metadata is deleted. -#[event] -pub struct ProfileMetadataDeleted { - pub profile_metadata: Pubkey, - pub profile: Pubkey, - pub user: Pubkey, - pub timestamp: i64, -} diff --git a/programs/gpl_core/src/instructions/badge.rs b/programs/gpl_core/src/instructions/badge.rs new file mode 100644 index 0000000..88055f0 --- /dev/null +++ b/programs/gpl_core/src/instructions/badge.rs @@ -0,0 +1,344 @@ +use crate::constants::*; +use crate::errors::GumError; +use crate::state::MAX_LEN_URI; +use crate::state::{Badge, Issuer, Profile, Schema}; +use std::str::FromStr; + +use anchor_lang::prelude::*; + +// Create a badge + +#[derive(Accounts)] +#[instruction(metadata_uri: String)] +pub struct CreateBadge<'info> { + #[account( + init, + seeds = [Badge::SEED_PREFIX.as_bytes(), issuer.key().as_ref(), schema.key().as_ref(), holder.key().as_ref()], + bump, + payer = authority, + space = Badge::LEN + )] + pub badge: Account<'info, Badge>, + #[account( + seeds = [Issuer::SEED_PREFIX.as_bytes(), authority.key().as_ref()], + bump, + has_one = authority, + constraint = issuer.verified @ GumError::UnverifiedIssuer + )] + pub issuer: Account<'info, Issuer>, + + #[account( + seeds = [ + PROFILE_PREFIX_SEED.as_bytes(), + holder.random_hash.as_ref(), + ], + bump, + )] + pub holder: Account<'info, Profile>, + + #[account( + seeds = [Schema::SEED_PREFIX.as_bytes(), schema.random_hash.as_ref()], + bump, + )] + pub schema: Account<'info, Schema>, + + /// CHECK the update_authority of the badge issuer + pub update_authority: Option>, + + #[account(mut)] + pub authority: Signer<'info>, + pub system_program: Program<'info, System>, +} + +// Handler to create a badge +pub fn create_badge_handler(ctx: Context, metadata_uri: String) -> Result<()> { + require!(metadata_uri.len() <= MAX_LEN_URI, GumError::URITooLong); + + let badge = &mut ctx.accounts.badge; + + badge.set_inner(Badge { + issuer: ctx.accounts.issuer.key(), + holder: ctx.accounts.holder.key(), + schema: ctx.accounts.schema.key(), + metadata_uri, + // If an update_authority is not provided, use the issuer ie current signer as the update_authority + update_authority: ctx + .accounts + .update_authority + .clone() + .map(|account| account.key()) + .unwrap_or(ctx.accounts.authority.key()), + }); + + Ok(()) +} + +// Update a badge +#[derive(Accounts)] +#[instruction(metadata_uri: String)] +pub struct UpdateBadge<'info> { + #[account( + mut, + seeds = [Badge::SEED_PREFIX.as_bytes(), issuer.key().as_ref(), schema.key().as_ref(), badge.holder.key().as_ref()], + bump, + has_one = issuer, + has_one = schema + )] + pub badge: Account<'info, Badge>, + #[account( + seeds = [Issuer::SEED_PREFIX.as_bytes(), issuer.authority.key().as_ref()], + bump, + constraint = issuer.verified @ GumError::UnverifiedIssuer + )] + pub issuer: Account<'info, Issuer>, + + #[account( + seeds = [Schema::SEED_PREFIX.as_bytes(), schema.random_hash.as_ref()], + bump, + )] + pub schema: Account<'info, Schema>, + + #[account( + // The badge can be updated by the issuer or update authority set in the badge + constraint = badge.update_authority == signer.key() || issuer.authority == signer.key() @ProgramError::MissingRequiredSignature + )] + pub signer: Signer<'info>, +} + +// Handler to update a badge +pub fn update_badge_handler(ctx: Context, metadata_uri: String) -> Result<()> { + require!(metadata_uri.len() <= MAX_LEN_URI, GumError::URITooLong); + + let badge = &mut ctx.accounts.badge; + + badge.metadata_uri = metadata_uri; + + Ok(()) +} + +// Burn a badge +// Either the holder or the issuer can burn a badge +#[derive(Accounts)] +pub struct BurnBadge<'info> { + #[account( + mut, + seeds = [Badge::SEED_PREFIX.as_bytes(), issuer.key().as_ref(), schema.key().as_ref(), holder.key().as_ref()], + bump, + has_one = issuer, + has_one = holder, + has_one = schema, + close = signer + )] + pub badge: Account<'info, Badge>, + + #[account( + seeds = [ + PROFILE_PREFIX_SEED.as_bytes(), + holder.random_hash.as_ref(), + ], + bump, + )] + pub holder: Account<'info, Profile>, + + #[account( + seeds = [Issuer::SEED_PREFIX.as_bytes(), issuer.authority.key().as_ref()], + bump, + constraint = issuer.verified @ GumError::UnverifiedIssuer + )] + pub issuer: Account<'info, Issuer>, + + #[account( + seeds = [Schema::SEED_PREFIX.as_bytes(), schema.random_hash.as_ref()], + bump, + )] + pub schema: Account<'info, Schema>, + + #[account( + mut, + constraint = signer.key() == holder.authority.key() || signer.key() == issuer.key() @ProgramError::MissingRequiredSignature + )] + pub signer: Signer<'info>, +} + +// Handler to burn a badge +pub fn burn_badge_handler(_: Context) -> Result<()> { + Ok(()) +} + +// Create a schema +#[derive(Accounts)] +#[instruction(metadata_uri: String, random_hash: [u8; 32])] +pub struct CreateSchema<'info> { + #[account( + init, + seeds = [Schema::SEED_PREFIX.as_bytes(), random_hash.as_ref()], + bump, + payer = authority, + space = Schema::LEN + )] + pub schema: Account<'info, Schema>, + + #[account(mut)] + pub authority: Signer<'info>, + pub system_program: Program<'info, System>, +} + +// Handler to create a schema +pub fn create_schema_handler( + ctx: Context, + metadata_uri: String, + random_hash: [u8; 32], +) -> Result<()> { + require_eq!( + ctx.accounts.authority.key(), + // FIXME: Move this to constant byte and importantly use a different key before deploying. + // This is a quick hack to test the patch. + Pubkey::from_str("Bi2ZL1UijCXwtNYi132NyMDRnzVxpuAVcgsqVuUgee5A").unwrap(), + GumError::UnauthorizedSigner + ); + require!(metadata_uri.len() <= MAX_LEN_URI, GumError::URITooLong); + + let schema = &mut ctx.accounts.schema; + + schema.set_inner(Schema { + authority: ctx.accounts.authority.key(), + metadata_uri, + random_hash, + }); + + Ok(()) +} + +// Update a schema +#[derive(Accounts)] +#[instruction(metadata_uri: String)] +pub struct UpdateSchema<'info> { + #[account( + mut, + seeds = [Schema::SEED_PREFIX.as_bytes(), schema.random_hash.as_ref()], + bump, + has_one = authority + )] + pub schema: Account<'info, Schema>, + + pub authority: Signer<'info>, +} + +// Handler to update a schema +pub fn update_schema_handler(ctx: Context, metadata_uri: String) -> Result<()> { + require_eq!( + ctx.accounts.authority.key(), + // FIXME: Move this to constant byte and importantly use a different key before deploying. + // This is a quick hack to test the patch. + Pubkey::from_str("Bi2ZL1UijCXwtNYi132NyMDRnzVxpuAVcgsqVuUgee5A").unwrap(), + GumError::UnauthorizedSigner + ); + require!(metadata_uri.len() <= MAX_LEN_URI, GumError::URITooLong); + + let schema = &mut ctx.accounts.schema; + + schema.metadata_uri = metadata_uri; + + Ok(()) +} + +// Delete a schema +#[derive(Accounts)] +pub struct DeleteSchema<'info> { + #[account( + mut, + seeds = [Schema::SEED_PREFIX.as_bytes(), schema.random_hash.as_ref()], + bump, + has_one = authority, + close = authority + )] + pub schema: Account<'info, Schema>, + + pub authority: Signer<'info>, +} + +// Handler to delete a schema +pub fn delete_schema_handler(ctx: Context) -> Result<()> { + require_eq!( + ctx.accounts.authority.key(), + // FIXME: Move this to constant byte and importantly use a different key before deploying. + // This is a quick hack to test the patch. + Pubkey::from_str("Bi2ZL1UijCXwtNYi132NyMDRnzVxpuAVcgsqVuUgee5A").unwrap(), + GumError::UnauthorizedSigner + ); + Ok(()) +} + +// Create an issuer +// TODO: Think about if the issuer should have a profile themselves +#[derive(Accounts)] +pub struct CreateIssuer<'info> { + #[account( + init, + seeds = [Issuer::SEED_PREFIX.as_bytes(), authority.key().as_ref()], + bump, + payer = authority, + space = Issuer::LEN + )] + pub issuer: Account<'info, Issuer>, + + #[account(mut)] + pub authority: Signer<'info>, + pub system_program: Program<'info, System>, +} + +// Handler to create an issuer +pub fn create_issuer_handler(ctx: Context) -> Result<()> { + let issuer = &mut ctx.accounts.issuer; + + issuer.set_inner(Issuer { + authority: ctx.accounts.authority.key(), + verified: false, + }); + + Ok(()) +} + +// Delete an issuer +#[derive(Accounts)] +pub struct DeleteIssuer<'info> { + #[account( + mut, + seeds = [Issuer::SEED_PREFIX.as_bytes(), authority.key().as_ref()], + bump, + has_one = authority, + close = authority + )] + pub issuer: Account<'info, Issuer>, + pub authority: Signer<'info>, +} +// Handler to delete an issuer +pub fn delete_issuer_handler(_: Context) -> Result<()> { + Ok(()) +} + +// Verify an issuer +#[derive(Accounts)] +pub struct VerifyIssuer<'info> { + #[account(mut)] + pub issuer: Account<'info, Issuer>, + + pub signer: Signer<'info>, +} + +// Handler to verify an issuer +pub fn verify_issuer_handler(ctx: Context) -> Result<()> { + require_eq!( + ctx.accounts.signer.key(), + // FIXME: Move this to constant byte and importantly use a different key before deploying. + // This is a quick hack to test the patch. + Pubkey::from_str("Bi2ZL1UijCXwtNYi132NyMDRnzVxpuAVcgsqVuUgee5A").unwrap(), + GumError::InvalidSignerToVerify + ); + + let issuer = &mut ctx.accounts.issuer; + + issuer.verified = true; + + Ok(()) +} diff --git a/programs/gpl_core/src/instructions/connection.rs b/programs/gpl_core/src/instructions/connection.rs index c1de3ff..75cc690 100644 --- a/programs/gpl_core/src/instructions/connection.rs +++ b/programs/gpl_core/src/instructions/connection.rs @@ -1,5 +1,5 @@ use crate::errors::GumError; -use crate::state::{Connection, Profile, User}; +use crate::state::{Connection, Profile}; use anchor_lang::prelude::*; use gpl_session::{session_auth_or, Session, SessionError, SessionToken}; use std::convert::AsRef; @@ -29,34 +29,16 @@ pub struct CreateConnection<'info> { #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - from_profile.namespace.as_ref().as_bytes(), - from_profile.user.as_ref(), + from_profile.random_hash.as_ref(), ], bump, - has_one = user, )] pub from_profile: Account<'info, Profile>, - #[account( - seeds = [ - PROFILE_PREFIX_SEED.as_bytes(), - to_profile.namespace.as_ref().as_bytes(), - to_profile.user.as_ref(), - ], - bump, - )] - pub to_profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - bump, - )] - pub user: Account<'info, User>, + pub to_profile: Account<'info, Profile>, #[session( signer = authority, - authority = user.authority.key() + authority = from_profile.authority.key() )] pub session_token: Option>, @@ -67,7 +49,7 @@ pub struct CreateConnection<'info> { // Handler to create a new Connection account #[session_auth_or( - ctx.accounts.user.authority.key() == ctx.accounts.authority.key(), + ctx.accounts.from_profile.authority.key() == ctx.accounts.authority.key(), GumError::UnauthorizedSigner )] pub fn create_connection_handler(ctx: Context) -> Result<()> { @@ -84,7 +66,6 @@ pub fn create_connection_handler(ctx: Context) -> Result<()> { // emit a new connection event emit!(ConnectionNew { connection: *connection.to_account_info().key, - user: *ctx.accounts.user.to_account_info().key, from_profile: *ctx.accounts.from_profile.to_account_info().key, to_profile: *ctx.accounts.to_profile.to_account_info().key, timestamp: Clock::get()?.unix_timestamp, @@ -113,41 +94,23 @@ pub struct DeleteConnection<'info> { #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - from_profile.namespace.as_ref().as_bytes(), - from_profile.user.as_ref(), + from_profile.random_hash.as_ref(), ], bump, - has_one = user, )] pub from_profile: Account<'info, Profile>, - #[account( - seeds = [ - PROFILE_PREFIX_SEED.as_bytes(), - to_profile.namespace.as_ref().as_bytes(), - to_profile.user.as_ref(), - ], - bump, - )] pub to_profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - bump, - )] - pub user: Account<'info, User>, #[session( signer = authority, - authority = user.authority.key() + authority = from_profile.authority.key() )] pub session_token: Option>, #[account(mut)] pub authority: Signer<'info>, - #[account(mut, constraint = refund_receiver.key() == user.authority)] + #[account(mut, constraint = refund_receiver.key() == from_profile.authority)] pub refund_receiver: SystemAccount<'info>, // The system program @@ -156,14 +119,13 @@ pub struct DeleteConnection<'info> { // Handler to delete a Connection account #[session_auth_or( - ctx.accounts.user.authority.key() == ctx.accounts.authority.key(), + ctx.accounts.from_profile.authority.key() == ctx.accounts.authority.key(), GumError::UnauthorizedSigner )] pub fn delete_connection_handler(ctx: Context) -> Result<()> { // emit a delete connection event emit!(ConnectionDeleted { connection: *ctx.accounts.connection.to_account_info().key, - user: *ctx.accounts.user.to_account_info().key, from_profile: *ctx.accounts.from_profile.to_account_info().key, to_profile: *ctx.accounts.to_profile.to_account_info().key, timestamp: Clock::get()?.unix_timestamp, diff --git a/programs/gpl_core/src/instructions/mod.rs b/programs/gpl_core/src/instructions/mod.rs index ec5227e..6bd1086 100644 --- a/programs/gpl_core/src/instructions/mod.rs +++ b/programs/gpl_core/src/instructions/mod.rs @@ -1,13 +1,11 @@ +mod badge; mod connection; mod post; mod profile; -mod profile_metadata; mod reaction; -mod user; +pub use badge::*; pub use connection::*; pub use post::*; pub use profile::*; -pub use profile_metadata::*; pub use reaction::*; -pub use user::*; diff --git a/programs/gpl_core/src/instructions/post.rs b/programs/gpl_core/src/instructions/post.rs index 405afed..a9cd0e2 100644 --- a/programs/gpl_core/src/instructions/post.rs +++ b/programs/gpl_core/src/instructions/post.rs @@ -1,6 +1,6 @@ use crate::errors::{GumError, PostError}; use crate::events::{PostCommentNew, PostDeleted, PostNew, PostUpdated}; -use crate::state::{Post, Profile, User, MAX_LEN_URI}; +use crate::state::{Post, Profile, MAX_LEN_URI}; use gpl_session::{session_auth_or, Session}; use anchor_lang::prelude::*; @@ -31,25 +31,15 @@ pub struct CreatePost<'info> { #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), + profile.random_hash.as_ref(), ], bump, - has_one = user, )] pub profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - bump, - )] - pub user: Account<'info, User>, #[session( signer = authority, - authority = user.authority.key() + authority = profile.authority.key() )] pub session_token: Option>, @@ -60,7 +50,7 @@ pub struct CreatePost<'info> { // Handler to create a new Post account #[session_auth_or( - ctx.accounts.user.authority.key() == ctx.accounts.authority.key(), + ctx.accounts.profile.authority.key() == ctx.accounts.authority.key(), GumError::UnauthorizedSigner )] pub fn create_post_handler( @@ -79,7 +69,6 @@ pub fn create_post_handler( emit!(PostNew { post: *post.to_account_info().key, profile: *ctx.accounts.profile.to_account_info().key, - user: *ctx.accounts.user.to_account_info().key, random_hash: random_hash, metadata_uri: post.metadata_uri.clone(), timestamp: Clock::get()?.unix_timestamp, @@ -105,24 +94,14 @@ pub struct UpdatePost<'info> { #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), + profile.random_hash.as_ref(), ], bump, - has_one = user, )] pub profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - bump, - )] - pub user: Account<'info, User>, #[session( signer = authority, - authority = user.authority.key() + authority = profile.authority.key() )] pub session_token: Option>, #[account(mut)] @@ -132,7 +111,7 @@ pub struct UpdatePost<'info> { // Handler to update a Post account #[session_auth_or( - ctx.accounts.user.authority.key() == ctx.accounts.authority.key(), + ctx.accounts.profile.authority.key() == ctx.accounts.authority.key(), GumError::UnauthorizedSigner )] pub fn update_post_handler(ctx: Context, metadata_uri: String) -> Result<()> { @@ -144,7 +123,6 @@ pub fn update_post_handler(ctx: Context, metadata_uri: String) -> Re emit!(PostUpdated { post: *post.to_account_info().key, profile: *ctx.accounts.profile.to_account_info().key, - user: *ctx.accounts.user.to_account_info().key, metadata_uri: post.metadata_uri.clone(), timestamp: Clock::get()?.unix_timestamp, }); @@ -172,21 +150,11 @@ pub struct CreateComment<'info> { #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), + profile.random_hash.as_ref(), ], bump, - has_one = user, )] pub profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - bump, - )] - pub user: Account<'info, User>, #[account( seeds = [ POST_PREFIX_SEED.as_bytes(), @@ -197,7 +165,7 @@ pub struct CreateComment<'info> { pub reply_to: Account<'info, Post>, #[session( signer = authority, - authority = user.authority.key() + authority = profile.authority.key() )] pub session_token: Option>, pub authority: Signer<'info>, @@ -207,7 +175,7 @@ pub struct CreateComment<'info> { // Handler to add a comment to a post #[session_auth_or( - ctx.accounts.user.authority.key() == ctx.accounts.authority.key(), + ctx.accounts.profile.authority.key() == ctx.accounts.authority.key(), GumError::UnauthorizedSigner )] pub fn create_comment_handler( @@ -227,7 +195,6 @@ pub fn create_comment_handler( emit!(PostCommentNew { post: *post.to_account_info().key, profile: *ctx.accounts.profile.to_account_info().key, - user: *ctx.accounts.user.to_account_info().key, random_hash: random_hash, metadata_uri: post.metadata_uri.clone(), reply_to: *ctx.accounts.reply_to.to_account_info().key, @@ -254,37 +221,26 @@ pub struct DeletePost<'info> { #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), + profile.random_hash.as_ref(), ], bump, - has_one = user, )] pub profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - bump, - )] - pub user: Account<'info, User>, - #[session( signer = authority, - authority = user.authority.key() + authority = profile.authority.key() )] pub session_token: Option>, #[account(mut)] pub authority: Signer<'info>, - #[account(mut, constraint = refund_receiver.key() == user.authority)] + #[account(mut, constraint = refund_receiver.key() == profile.authority)] pub refund_receiver: SystemAccount<'info>, pub system_program: Program<'info, System>, } // Handler to delete a Post account #[session_auth_or( - ctx.accounts.user.authority.key() == ctx.accounts.authority.key(), + ctx.accounts.profile.authority.key() == ctx.accounts.authority.key(), GumError::UnauthorizedSigner )] pub fn delete_post_handler(ctx: Context) -> Result<()> { @@ -292,7 +248,6 @@ pub fn delete_post_handler(ctx: Context) -> Result<()> { emit!(PostDeleted { post: *ctx.accounts.post.to_account_info().key, profile: *ctx.accounts.profile.to_account_info().key, - user: *ctx.accounts.user.to_account_info().key, timestamp: Clock::get()?.unix_timestamp, }); Ok(()) diff --git a/programs/gpl_core/src/instructions/profile.rs b/programs/gpl_core/src/instructions/profile.rs index b49eb79..3a4b215 100644 --- a/programs/gpl_core/src/instructions/profile.rs +++ b/programs/gpl_core/src/instructions/profile.rs @@ -1,14 +1,14 @@ -use crate::state::{Namespace, Profile, User}; +use crate::state::Profile; use anchor_lang::prelude::*; -use std::convert::AsRef; -use std::str::FromStr; use crate::constants::*; -use crate::events::{ProfileDeleted, ProfileNew}; +use crate::events::{ProfileDeleted, ProfileNew, ProfileUpdated}; + +use gpl_nameservice::validate as validate_screen_name; // Initialize a new profile account #[derive(Accounts)] -#[instruction(namespace: String)] +#[instruction(random_hash: [u8; 32], metadata_uri: String)] pub struct CreateProfile<'info> { #[account(mut)] pub payer: Signer<'info>, @@ -17,69 +17,99 @@ pub struct CreateProfile<'info> { init, seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - namespace.as_bytes(), - user.to_account_info().key.as_ref() + random_hash.as_ref(), ], bump, payer = payer, space = Profile::LEN )] pub profile: Account<'info, Profile>, + /// CHECK that this PDA is either SNS, ANS or GPL Nameservice #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - bump, - has_one = authority, + constraint = validate_screen_name(&[screen_name.clone(), authority.to_account_info()])?, )] - pub user: Account<'info, User>, + pub screen_name: AccountInfo<'info>, + pub authority: Signer<'info>, // The system program pub system_program: Program<'info, System>, } // Handler to create a new Profile account -pub fn create_profile_handler(ctx: Context, namespace: String) -> Result<()> { +pub fn create_profile_handler( + ctx: Context, + random_hash: [u8; 32], + metadata_uri: String, +) -> Result<()> { let profile = &mut ctx.accounts.profile; - profile.namespace = Namespace::from_str(&namespace).unwrap(); - profile.user = *ctx.accounts.user.to_account_info().key; - + profile.set_inner(Profile { + authority: *ctx.accounts.authority.key, + random_hash, + metadata_uri, + screen_name: *ctx.accounts.screen_name.key, + }); // Emit new profile event emit!(ProfileNew { profile: *profile.to_account_info().key, - namespace: profile.namespace, - user: *ctx.accounts.user.to_account_info().key, + authority: *ctx.accounts.authority.key, + random_hash, timestamp: Clock::get()?.unix_timestamp, + screen_name: profile.screen_name, + metadata_uri: profile.metadata_uri.clone(), }); Ok(()) } -// Delete a profile account +// Update a profile account #[derive(Accounts)] -pub struct DeleteProfile<'info> { - // The Profile account to delete +#[instruction(metadata_uri: String)] +pub struct UpdateProfile<'info> { #[account( mut, seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - profile.namespace.as_ref().as_bytes(), - profile.user.as_ref(), + profile.random_hash.as_ref(), ], bump, - has_one = user, - close = authority, + has_one = authority, )] pub profile: Account<'info, Profile>, + + /// CHECK that this PDA is either SNS, ANS or GPL Nameservice and is owned by the user + pub screen_name: AccountInfo<'info>, + + #[account(mut)] + pub authority: Signer<'info>, +} + +// Handler to update a Profile account +pub fn update_profile_handler(ctx: Context, metadata_uri: String) -> Result<()> { + let profile = &mut ctx.accounts.profile; + profile.metadata_uri = metadata_uri; + // Emit a profile update event + emit!(ProfileUpdated { + profile: *profile.to_account_info().key, + timestamp: Clock::get()?.unix_timestamp, + screen_name: profile.screen_name, + metadata_uri: profile.metadata_uri.clone(), + }); + Ok(()) +} + +// Delete a profile account +#[derive(Accounts)] +pub struct DeleteProfile<'info> { #[account( + mut, seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), + PROFILE_PREFIX_SEED.as_bytes(), + profile.random_hash.as_ref(), ], bump, has_one = authority, + close = authority, )] - pub user: Account<'info, User>, + pub profile: Account<'info, Profile>, #[account(mut)] pub authority: Signer<'info>, } @@ -89,9 +119,9 @@ pub fn delete_profile_handler(ctx: Context) -> Result<()> { // Emit profile deleted event emit!(ProfileDeleted { profile: *ctx.accounts.profile.to_account_info().key, - namespace: ctx.accounts.profile.namespace, - user: *ctx.accounts.user.to_account_info().key, timestamp: Clock::get()?.unix_timestamp, + screen_name: ctx.accounts.profile.screen_name, + metadata_uri: ctx.accounts.profile.metadata_uri.clone(), }); Ok(()) } diff --git a/programs/gpl_core/src/instructions/profile_metadata.rs b/programs/gpl_core/src/instructions/profile_metadata.rs deleted file mode 100644 index 57db5e5..0000000 --- a/programs/gpl_core/src/instructions/profile_metadata.rs +++ /dev/null @@ -1,188 +0,0 @@ -use crate::errors::ProfileMetadataError; -use crate::events::{ProfileMetadataDeleted, ProfileMetadataNew, ProfileMetadataUpdated}; -use crate::state::{Profile, ProfileMetadata, User, MAX_LEN_URI}; - -use anchor_lang::prelude::*; -use std::convert::AsRef; - -use crate::constants::*; - -// Create ProfileMetadata -#[derive(Accounts)] -#[instruction(metadata_uri: String)] -pub struct CreateProfileMetadata<'info> { - #[account(mut)] - pub payer: Signer<'info>, - // The account that will be initialized as a ProfileMetadata - #[account( - init, - seeds = [ - PROFILE_METADATA_PREFIX_SEED.as_bytes(), - profile.to_account_info().key.as_ref(), - ], - bump, - payer = payer, - space = ProfileMetadata::LEN - )] - pub profile_metadata: Account<'info, ProfileMetadata>, - #[account( - seeds = [ - PROFILE_PREFIX_SEED.as_bytes(), - profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), - ], - bump, - has_one = user, - )] - pub profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - bump, - has_one = authority, - )] - pub user: Account<'info, User>, - pub authority: Signer<'info>, - // The system program - pub system_program: Program<'info, System>, -} - -// Handler to create a new ProfileMetadata account -pub fn create_profile_metadata_handler( - ctx: Context, - metadata_uri: String, -) -> Result<()> { - // CHECK metadata_uri length - require!( - metadata_uri.len() <= MAX_LEN_URI, - ProfileMetadataError::URITooLong - ); - - let profile_metadata = &mut ctx.accounts.profile_metadata; - profile_metadata.metadata_uri = metadata_uri; - profile_metadata.profile = *ctx.accounts.profile.to_account_info().key; - // emit new ProfileMetadata event - emit!(ProfileMetadataNew { - profile_metadata: *profile_metadata.to_account_info().key, - profile: *ctx.accounts.profile.to_account_info().key, - user: *ctx.accounts.user.to_account_info().key, - metadata_uri: profile_metadata.metadata_uri.clone(), - timestamp: Clock::get()?.unix_timestamp, - }); - Ok(()) -} - -// Update a ProfileMetadata account -#[derive(Accounts)] -#[instruction(metadata_uri: String)] -pub struct UpdateProfileMetadata<'info> { - // The ProfileMetadata account to update - #[account( - mut, - seeds = [ - PROFILE_METADATA_PREFIX_SEED.as_bytes(), - profile.to_account_info().key.as_ref(), - ], - bump, - has_one = profile, - )] - pub profile_metadata: Account<'info, ProfileMetadata>, - #[account( - seeds = [ - PROFILE_PREFIX_SEED.as_bytes(), - profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), - ], - bump, - has_one = user, - )] - pub profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - bump, - has_one = authority, - )] - pub user: Account<'info, User>, - #[account(mut)] - pub authority: Signer<'info>, - pub system_program: Program<'info, System>, -} - -// Handler to update a ProfileMetadata account -pub fn update_profile_metadata_handler( - ctx: Context, - metadata_uri: String, -) -> Result<()> { - // CHECK metadata_uri length - require!( - metadata_uri.len() <= MAX_LEN_URI, - ProfileMetadataError::URITooLong - ); - let profile_metadata = &mut ctx.accounts.profile_metadata; - profile_metadata.metadata_uri = metadata_uri; - // emit update ProfileMetadata event - emit!(ProfileMetadataUpdated { - profile_metadata: *profile_metadata.to_account_info().key, - profile: *ctx.accounts.profile.to_account_info().key, - user: *ctx.accounts.user.to_account_info().key, - metadata_uri: profile_metadata.metadata_uri.clone(), - timestamp: Clock::get()?.unix_timestamp, - }); - Ok(()) -} - -// Delete a ProfileMetadata account -#[derive(Accounts)] -pub struct DeleteProfileMetadata<'info> { - // The ProfileMetadata account to delete - #[account( - mut, - seeds = [ - PROFILE_METADATA_PREFIX_SEED.as_bytes(), - profile.to_account_info().key.as_ref(), - ], - bump, - has_one = profile, - close = authority, - )] - pub profile_metadata: Account<'info, ProfileMetadata>, - #[account( - seeds = [ - PROFILE_PREFIX_SEED.as_bytes(), - profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), - ], - bump, - has_one = user, - )] - pub profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - bump, - has_one = authority, - )] - pub user: Account<'info, User>, - #[account(mut)] - pub authority: Signer<'info>, - pub system_program: Program<'info, System>, -} - -// Handler to delete a ProfileMetadata account -pub fn delete_profile_metadata_handler(ctx: Context) -> Result<()> { - // emit delete ProfileMetadata event - emit!(ProfileMetadataDeleted { - profile_metadata: *ctx.accounts.profile_metadata.to_account_info().key, - profile: *ctx.accounts.profile.to_account_info().key, - user: *ctx.accounts.user.to_account_info().key, - timestamp: Clock::get()?.unix_timestamp, - }); - Ok(()) -} diff --git a/programs/gpl_core/src/instructions/reaction.rs b/programs/gpl_core/src/instructions/reaction.rs index 9d8cdb9..b0aa0e0 100644 --- a/programs/gpl_core/src/instructions/reaction.rs +++ b/programs/gpl_core/src/instructions/reaction.rs @@ -1,9 +1,7 @@ use crate::errors::GumError; -use crate::state::{Post, Profile, Reaction, ReactionType, User}; +use crate::state::{Post, Profile, Reaction}; use anchor_lang::prelude::*; -use std::convert::AsRef; -use std::str::FromStr; use crate::constants::*; use crate::events::{ReactionDeleted, ReactionNew}; @@ -29,36 +27,19 @@ pub struct CreateReaction<'info> { space = Reaction::LEN )] pub reaction: Account<'info, Reaction>, - #[account( - seeds = [ - POST_PREFIX_SEED.as_bytes(), - to_post.random_hash.as_ref(), - ], - bump, - )] pub to_post: Account<'info, Post>, #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - from_profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), + from_profile.random_hash.as_ref(), ], bump, - has_one = user, )] pub from_profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - bump, - )] - pub user: Account<'info, User>, #[session( signer = authority, - authority = user.authority.key() + authority = from_profile.authority.key() )] pub session_token: Option>, @@ -70,20 +51,20 @@ pub struct CreateReaction<'info> { // Handler to create a new Reaction account #[session_auth_or( - ctx.accounts.user.authority.key() == ctx.accounts.authority.key(), + ctx.accounts.from_profile.authority.key() == ctx.accounts.authority.key(), GumError::UnauthorizedSigner )] pub fn create_reaction_handler(ctx: Context, reaction_type: String) -> Result<()> { + Reaction::validate_reaction_type(&reaction_type)?; let reaction = &mut ctx.accounts.reaction; - reaction.reaction_type = ReactionType::from_str(&reaction_type).unwrap(); + reaction.reaction_type = reaction_type; reaction.to_post = *ctx.accounts.to_post.to_account_info().key; reaction.from_profile = *ctx.accounts.from_profile.to_account_info().key; // emit a new reaction event emit!(ReactionNew { reaction: *reaction.to_account_info().key, - reaction_type: reaction.reaction_type, - user: *ctx.accounts.user.to_account_info().key, + reaction_type: reaction.reaction_type.clone(), to_post: *ctx.accounts.to_post.to_account_info().key, from_profile: *ctx.accounts.from_profile.to_account_info().key, timestamp: Clock::get()?.unix_timestamp, @@ -99,7 +80,7 @@ pub struct DeleteReaction<'info> { mut, seeds = [ REACTION_PREFIX_SEED.as_bytes(), - reaction.reaction_type.as_ref().as_bytes(), + reaction.reaction_type.as_ref(), reaction.to_post.as_ref(), reaction.from_profile.as_ref(), ], @@ -109,42 +90,26 @@ pub struct DeleteReaction<'info> { close = refund_receiver, )] pub reaction: Account<'info, Reaction>, - #[account( - seeds = [ - POST_PREFIX_SEED.as_bytes(), - to_post.random_hash.as_ref(), - ], - bump, - )] pub to_post: Account<'info, Post>, #[account( seeds = [ PROFILE_PREFIX_SEED.as_bytes(), - from_profile.namespace.as_ref().as_bytes(), - user.to_account_info().key.as_ref(), + from_profile.random_hash.as_ref(), ], bump, - has_one = user, )] pub from_profile: Account<'info, Profile>, - #[account( - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - bump, - )] - pub user: Account<'info, User>, #[session( signer = authority, - authority = user.authority.key() + authority = from_profile.authority.key() )] pub session_token: Option>, + #[account(mut)] pub authority: Signer<'info>, - #[account(mut, constraint = refund_receiver.key() == user.authority)] + #[account(mut, constraint = refund_receiver.key() == from_profile.authority)] pub refund_receiver: SystemAccount<'info>, // The system program @@ -153,15 +118,14 @@ pub struct DeleteReaction<'info> { // Handler to delete a Reaction account #[session_auth_or( - ctx.accounts.user.authority.key() == ctx.accounts.authority.key(), + ctx.accounts.from_profile.authority.key() == ctx.accounts.authority.key(), GumError::UnauthorizedSigner )] pub fn delete_reaction_handler(ctx: Context) -> Result<()> { // emit a reaction deleted event emit!(ReactionDeleted { reaction: *ctx.accounts.reaction.to_account_info().key, - reaction_type: ctx.accounts.reaction.reaction_type, - user: *ctx.accounts.user.to_account_info().key, + reaction_type: ctx.accounts.reaction.reaction_type.to_string(), to_post: *ctx.accounts.to_post.to_account_info().key, from_profile: *ctx.accounts.from_profile.to_account_info().key, timestamp: Clock::get()?.unix_timestamp, diff --git a/programs/gpl_core/src/instructions/user.rs b/programs/gpl_core/src/instructions/user.rs deleted file mode 100644 index 8cdeaa5..0000000 --- a/programs/gpl_core/src/instructions/user.rs +++ /dev/null @@ -1,115 +0,0 @@ -use anchor_lang::prelude::*; - -use crate::constants::*; -use crate::events::{UserAuthorityChanged, UserDeleted, UserNew}; -use crate::state::User; - -// Initialize a new user account -#[derive(Accounts)] -#[instruction(random_hash: [u8;32])] -pub struct CreateUser<'info> { - #[account(mut)] - pub payer: Signer<'info>, - // The account that will be initialized as a user - #[account( - init, - seeds = [ - USER_PREFIX_SEED.as_bytes(), - random_hash.as_ref(), - ], - bump, - payer = payer, - space = User::LEN - )] - pub user: Account<'info, User>, - // The authority of the user - pub authority: Signer<'info>, - // The system program - pub system_program: Program<'info, System>, -} - -// Handler to create a new user account -pub fn create_user_handler(ctx: Context, random_hash: [u8; 32]) -> Result<()> { - let user = &mut ctx.accounts.user; - user.random_hash = random_hash; - user.authority = *ctx.accounts.authority.key; - - // emit new user event - emit!(UserNew { - user: *user.to_account_info().key, - random_hash: random_hash, - authority: *ctx.accounts.authority.key, - timestamp: Clock::get()?.unix_timestamp, - }); - - Ok(()) -} - -// Update a user account with new authority -#[derive(Accounts)] -pub struct UpdateUser<'info> { - // The user account to update - #[account( - mut, - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - bump, - has_one = authority, - )] - pub user: Account<'info, User>, - - // The new authority of the user - pub new_authority: SystemAccount<'info>, - // The authority of the user - pub authority: Signer<'info>, - pub system_program: Program<'info, System>, -} - -// Handler to update a user account with new authority -pub fn update_user_handler(ctx: Context) -> Result<()> { - let user = &mut ctx.accounts.user; - user.authority = *ctx.accounts.new_authority.key; - // Emit user authority changed event - emit!(UserAuthorityChanged { - user: *user.to_account_info().key, - old_authority: *ctx.accounts.authority.key, - new_authority: *ctx.accounts.new_authority.key, - timestamp: Clock::get()?.unix_timestamp, - }); - Ok(()) -} - -// Delete a user account -#[derive(Accounts)] -pub struct DeleteUser<'info> { - // The user account to close - #[account( - mut, - seeds = [ - USER_PREFIX_SEED.as_bytes(), - user.random_hash.as_ref(), - ], - bump, - has_one = authority, - close = authority - )] - pub user: Account<'info, User>, - - // The authority of the user - #[account(mut)] - pub authority: Signer<'info>, - pub system_program: Program<'info, System>, -} - -// Handler to close a user account -pub fn delete_user_handler(ctx: Context) -> Result<()> { - // Emit user deleted event - emit!(UserDeleted { - user: *ctx.accounts.user.to_account_info().key, - authority: *ctx.accounts.authority.key, - timestamp: Clock::get()?.unix_timestamp, - }); - Ok(()) -} diff --git a/programs/gpl_core/src/lib.rs b/programs/gpl_core/src/lib.rs index 37c91da..69f7ea9 100644 --- a/programs/gpl_core/src/lib.rs +++ b/programs/gpl_core/src/lib.rs @@ -1,5 +1,4 @@ use anchor_lang::prelude::*; -use solana_security_txt::security_txt; pub mod constants; pub mod errors; @@ -9,10 +8,10 @@ pub mod state; use instructions::*; -declare_id!("CDDMdCAWB5AXgvEy7XJRggAu37QPG1b9aJXndZoPUkkm"); +declare_id!("6MhUAJtKdJx3RDCffUsJsQm8xy9YhhywjEmMYrxRc5j6"); #[cfg(not(feature = "no-entrypoint"))] -security_txt! { +solana_security_txt::security_txt! { name: "gpl_core", project_url: "https://gum.fun", contacts: "email:hello@gum.fun,twitter:@gumisfunn", @@ -26,50 +25,23 @@ pub mod gpl_core { use super::*; - // Create a new user account - pub fn create_user(ctx: Context, random_hash: [u8; 32]) -> Result<()> { - create_user_handler(ctx, random_hash) - } - - // Update a user account with new authority - pub fn update_user(ctx: Context) -> Result<()> { - update_user_handler(ctx) - } - - // Delete a user account - pub fn delete_user(ctx: Context) -> Result<()> { - delete_user_handler(ctx) - } - // Create a new profile account - pub fn create_profile(ctx: Context, namespace: String) -> Result<()> { - create_profile_handler(ctx, namespace) - } - - // Delete a profile account - pub fn delete_profile(ctx: Context) -> Result<()> { - delete_profile_handler(ctx) - } - - // create a new profile_metadata account - pub fn create_profile_metadata( - ctx: Context, + pub fn create_profile( + ctx: Context, + random_hash: [u8; 32], metadata_uri: String, ) -> Result<()> { - create_profile_metadata_handler(ctx, metadata_uri) + create_profile_handler(ctx, random_hash, metadata_uri) } - // update a profile_metadata - pub fn update_profile_metadata( - ctx: Context, - metadata_uri: String, - ) -> Result<()> { - update_profile_metadata_handler(ctx, metadata_uri) + // update a profile account + pub fn update_profile(ctx: Context, metadata_uri: String) -> Result<()> { + update_profile_handler(ctx, metadata_uri) } - // delete a profile_metadata - pub fn delete_profile_metadata(ctx: Context) -> Result<()> { - delete_profile_metadata_handler(ctx) + // Delete a profile account + pub fn delete_profile(ctx: Context) -> Result<()> { + delete_profile_handler(ctx) } // create a new post account @@ -112,6 +84,7 @@ pub mod gpl_core { // create a reaction account with reaction type pub fn create_reaction(ctx: Context, reaction_type: String) -> Result<()> { + // By default, reactions are not custom create_reaction_handler(ctx, reaction_type) } @@ -119,4 +92,53 @@ pub mod gpl_core { pub fn delete_reaction(ctx: Context) -> Result<()> { delete_reaction_handler(ctx) } + + // create a badge account + pub fn create_badge(ctx: Context, metadata_uri: String) -> Result<()> { + create_badge_handler(ctx, metadata_uri) + } + + // update a badge + pub fn update_badge(ctx: Context, metadata_uri: String) -> Result<()> { + update_badge_handler(ctx, metadata_uri) + } + + // burn a badge + pub fn burn_badge(ctx: Context) -> Result<()> { + burn_badge_handler(ctx) + } + + // create an issuer account + pub fn create_issuer(ctx: Context) -> Result<()> { + create_issuer_handler(ctx) + } + + // verify an issuer + pub fn verify_issuer(ctx: Context) -> Result<()> { + verify_issuer_handler(ctx) + } + + // delete an issuer + pub fn delete_issuer(ctx: Context) -> Result<()> { + delete_issuer_handler(ctx) + } + + // create a schema account + pub fn create_schema( + ctx: Context, + metadata_uri: String, + random_hash: [u8; 32], + ) -> Result<()> { + create_schema_handler(ctx, metadata_uri, random_hash) + } + + // update a schema + pub fn update_schema(ctx: Context, metadata_uri: String) -> Result<()> { + update_schema_handler(ctx, metadata_uri) + } + + // delete a schema + pub fn delete_schema(ctx: Context) -> Result<()> { + delete_schema_handler(ctx) + } } diff --git a/programs/gpl_core/src/state/badge.rs b/programs/gpl_core/src/state/badge.rs new file mode 100644 index 0000000..fb18caa --- /dev/null +++ b/programs/gpl_core/src/state/badge.rs @@ -0,0 +1,44 @@ +use crate::state::MAX_LEN_URI; +use anchor_lang::prelude::*; +use std::mem::size_of; + +#[account] +pub struct Badge { + pub issuer: Pubkey, + // Profile of the user who earned the badge + pub holder: Pubkey, + pub update_authority: Pubkey, + pub schema: Pubkey, + pub metadata_uri: String, +} + +impl Badge { + pub const SEED_PREFIX: &'static str = "badge"; + + pub const LEN: usize = 8 + 64 + MAX_LEN_URI + size_of::(); +} + +#[account] +pub struct Issuer { + pub authority: Pubkey, + pub verified: bool, +} + +impl Issuer { + pub const SEED_PREFIX: &'static str = "issuer"; + + pub const LEN: usize = 8 + 64 + size_of::(); +} + +#[account] +pub struct Schema { + pub authority: Pubkey, + pub metadata_uri: String, + pub random_hash: [u8; 32], +} + +impl Schema { + pub const SEED_PREFIX: &'static str = "schema"; + + pub const LEN: usize = 8 + 64 + MAX_LEN_URI + size_of::(); +} diff --git a/programs/gpl_core/src/state/mod.rs b/programs/gpl_core/src/state/mod.rs index ec5227e..6bd1086 100644 --- a/programs/gpl_core/src/state/mod.rs +++ b/programs/gpl_core/src/state/mod.rs @@ -1,13 +1,11 @@ +mod badge; mod connection; mod post; mod profile; -mod profile_metadata; mod reaction; -mod user; +pub use badge::*; pub use connection::*; pub use post::*; pub use profile::*; -pub use profile_metadata::*; pub use reaction::*; -pub use user::*; diff --git a/programs/gpl_core/src/state/post.rs b/programs/gpl_core/src/state/post.rs index 6c96bd0..845f450 100644 --- a/programs/gpl_core/src/state/post.rs +++ b/programs/gpl_core/src/state/post.rs @@ -3,7 +3,6 @@ use anchor_lang::prelude::*; pub const MAX_LEN_URI: usize = 128; #[account] -#[derive(Default, Debug)] pub struct Post { pub profile: Pubkey, pub metadata_uri: String, diff --git a/programs/gpl_core/src/state/profile.rs b/programs/gpl_core/src/state/profile.rs index ed88dd8..a30f3a2 100644 --- a/programs/gpl_core/src/state/profile.rs +++ b/programs/gpl_core/src/state/profile.rs @@ -1,30 +1,20 @@ +use crate::state::MAX_LEN_URI; use anchor_lang::prelude::*; -use strum_macros::{AsRefStr, EnumString}; - #[account] pub struct Profile { // The user PDA that owns this profile - pub user: Pubkey, - // The namespace that this profile is in - pub namespace: Namespace, - // should there be metadata here? -} + pub authority: Pubkey, -impl Profile { - pub const LEN: usize = 8 + std::mem::size_of::(); + // This collapses the ProfileMetadata PDA into the Profile struct. + pub metadata_uri: String, + + // External reference to SNS, ANS or GPL Nameservice + pub screen_name: Pubkey, + + pub random_hash: [u8; 32], } -#[derive( - AnchorSerialize, AnchorDeserialize, Clone, Copy, Debug, PartialEq, AsRefStr, EnumString, -)] -pub enum Namespace { - #[strum(ascii_case_insensitive)] - Professional, - #[strum(ascii_case_insensitive)] - Personal, - #[strum(ascii_case_insensitive)] - Gaming, - #[strum(ascii_case_insensitive)] - Degen, +impl Profile { + pub const LEN: usize = 8 + MAX_LEN_URI + std::mem::size_of::(); } diff --git a/programs/gpl_core/src/state/profile_metadata.rs b/programs/gpl_core/src/state/profile_metadata.rs deleted file mode 100644 index 7448047..0000000 --- a/programs/gpl_core/src/state/profile_metadata.rs +++ /dev/null @@ -1,13 +0,0 @@ -use anchor_lang::prelude::*; - -use crate::state::{MAX_LEN_URI}; - -#[account] -pub struct ProfileMetadata { - pub profile: Pubkey, - pub metadata_uri: String, -} - -impl ProfileMetadata { - pub const LEN: usize = 8 + std::mem::size_of::() + MAX_LEN_URI; -} diff --git a/programs/gpl_core/src/state/reaction.rs b/programs/gpl_core/src/state/reaction.rs index a457fa8..dd5b651 100644 --- a/programs/gpl_core/src/state/reaction.rs +++ b/programs/gpl_core/src/state/reaction.rs @@ -1,37 +1,30 @@ +use crate::errors::GumError; use anchor_lang::prelude::*; -use strum_macros::{AsRefStr, EnumString}; - #[account] pub struct Reaction { // The profile that owns this reaction pub from_profile: Pubkey, // The post that this reaction is to pub to_post: Pubkey, - pub reaction_type: ReactionType, + // NOTE: + // The burden of validating the reaction is on the client + // Since it is hard to define what a valid reaction is and will vary from app to app + // It's better to let the client decide what is valid + // + // Might change this to a [u8; 32] in the future + pub reaction_type: String, } impl Reaction { - pub const LEN: usize = 8 + std::mem::size_of::(); -} + pub const REACTION_TYPE_MAX_LEN: usize = 32; + pub const LEN: usize = 8 + 64 + Self::REACTION_TYPE_MAX_LEN + std::mem::size_of::(); -// Probably better to use emoji codes instead of strings -#[derive( - AnchorSerialize, AnchorDeserialize, Clone, Copy, Debug, PartialEq, AsRefStr, EnumString, -)] -pub enum ReactionType { - #[strum(ascii_case_insensitive)] - Like, - #[strum(ascii_case_insensitive)] - Dislike, - #[strum(ascii_case_insensitive)] - Love, - #[strum(ascii_case_insensitive)] - Haha, - #[strum(ascii_case_insensitive)] - Wow, - #[strum(ascii_case_insensitive)] - Sad, - #[strum(ascii_case_insensitive)] - Angry, + pub fn validate_reaction_type(reaction_type: &str) -> Result<()> { + require!( + reaction_type.len() <= Self::REACTION_TYPE_MAX_LEN, + GumError::ReactionTypeTooLong + ); + Ok(()) + } } diff --git a/programs/gpl_core/src/state/user.rs b/programs/gpl_core/src/state/user.rs deleted file mode 100644 index 50cd845..0000000 --- a/programs/gpl_core/src/state/user.rs +++ /dev/null @@ -1,16 +0,0 @@ -use anchor_lang::prelude::*; - -#[account] -pub struct User { - // The public key of the wallet that owns this User - // We use this PDA as a seed to derive other downstream - // accounts. - // - // User -> Profile -> Post -> [Connection, Reaction] - pub authority: Pubkey, - pub random_hash: [u8; 32], -} - -impl User { - pub const LEN: usize = 8 + std::mem::size_of::(); -} diff --git a/programs/gpl_nameservice/src/lib.rs b/programs/gpl_nameservice/src/lib.rs index fa9069a..0dbfdff 100644 --- a/programs/gpl_nameservice/src/lib.rs +++ b/programs/gpl_nameservice/src/lib.rs @@ -5,7 +5,7 @@ mod nameservice; pub use nameservice::*; -declare_id!("7LEuQxAEegasvBSq7dDrMregc3mrDtTyHiytNK9pU68u"); +declare_id!("5kWEYrdyryq3jGP5sUcKwTySzxr3dHzWFBVA3vkt6Nj5"); #[program] pub mod gpl_nameservice { diff --git a/programs/gpl_nameservice/src/nameservice/gpl_nameservice.rs b/programs/gpl_nameservice/src/nameservice/gpl_nameservice.rs index a7d701f..e202506 100644 --- a/programs/gpl_nameservice/src/nameservice/gpl_nameservice.rs +++ b/programs/gpl_nameservice/src/nameservice/gpl_nameservice.rs @@ -7,7 +7,7 @@ impl NameServiceParser for GplNameService { type ServiceName = NameRecord; fn id_str() -> &'static str { - "7LEuQxAEegasvBSq7dDrMregc3mrDtTyHiytNK9pU68u" + "5kWEYrdyryq3jGP5sUcKwTySzxr3dHzWFBVA3vkt6Nj5" } fn unpack(record: &AccountInfo) -> Result { diff --git a/test_keys/issuer_verify.json b/test_keys/issuer_verify.json new file mode 100644 index 0000000..e14c2f1 --- /dev/null +++ b/test_keys/issuer_verify.json @@ -0,0 +1 @@ +[190,216,168,153,11,254,227,62,53,162,176,244,248,202,204,242,191,62,60,181,191,52,37,205,244,246,107,34,93,112,190,253,159,23,113,128,89,101,47,136,12,173,177,103,86,234,51,212,209,126,30,115,244,209,47,21,50,155,71,106,111,31,215,61] \ No newline at end of file diff --git a/tests/gpl_compression/comment.spec.ts b/tests/gpl_compression/comment.spec.ts index a1ecfc8..6c5e501 100644 --- a/tests/gpl_compression/comment.spec.ts +++ b/tests/gpl_compression/comment.spec.ts @@ -21,6 +21,10 @@ import { Keypair, PublicKey } from "@solana/web3.js"; import { expect } from "chai"; import randomBytes from "randombytes"; +import { createGumDomain, createGumTld } from "../utils/index"; + +import { faker } from "@faker-js/faker"; + anchor.setProvider(anchor.AnchorProvider.env()); const rpcConnection = anchor.getProvider().connection; @@ -30,10 +34,8 @@ describe("Comment Compression", async () => { let treeConfigPDA: PublicKey; let offChainTree: MerkleTree; - let userPDA: PublicKey; let profilePDA: PublicKey; let postPDA: PublicKey; - let reactionPDA: PublicKey; beforeEach(async () => { // Setup a new keypair and airdrop some SOL @@ -52,17 +54,19 @@ describe("Comment Compression", async () => { offChainTree = treeResult.offChainTree; const randomHash = randomBytes(32); - const userTx = gpl_core.methods.createUser(randomHash).accounts({ - authority: payer.publicKey, - }); - const userPubKeys = await userTx.pubkeys(); - userPDA = userPubKeys.user as anchor.web3.PublicKey; - await userTx.signers([payer]).rpc(); + + const gumTld = await createGumTld(); // Create a profile + const profileMetdataUri = "https://example.com"; + const screenName = await createGumDomain( + gumTld, + faker.internet.userName(), + payer + ); const profileTx = gpl_core.methods - .createProfile("Personal") - .accounts({ user: userPDA, authority: payer.publicKey }); + .createProfile(randomHash, profileMetdataUri) + .accounts({ authority: payer.publicKey, screenName }); const profilePubKeys = await profileTx.pubkeys(); profilePDA = profilePubKeys.profile as anchor.web3.PublicKey; await profileTx.signers([payer]).rpc(); @@ -81,7 +85,6 @@ describe("Comment Compression", async () => { await gpl_compression.methods .createCompressedPost(metadataUri, postRandomHash) .accounts({ - user: userPDA, profile: profilePDA, treeConfig: treeConfigPDA, merkleTree, @@ -127,7 +130,6 @@ describe("Comment Compression", async () => { index ) .accounts({ - user: userPDA, fromProfile: profilePDA, treeConfig: treeConfigPDA, merkleTree, diff --git a/tests/gpl_compression/connection.spec.ts b/tests/gpl_compression/connection.spec.ts index ce7acaa..c547d6b 100644 --- a/tests/gpl_compression/connection.spec.ts +++ b/tests/gpl_compression/connection.spec.ts @@ -6,6 +6,8 @@ import { gpl_compression, setupTree, to_leaf, + createGumTld, + createGumDomain, } from "../utils/index"; import { @@ -20,13 +22,14 @@ import { Keypair, PublicKey } from "@solana/web3.js"; import { expect } from "chai"; import randomBytes from "randombytes"; +import { faker } from "@faker-js/faker"; + anchor.setProvider(anchor.AnchorProvider.env()); const rpcConnection = anchor.getProvider().connection; describe("Connection Compression", async () => { let payer: Keypair; let merkleTree: PublicKey; - let userPDA: PublicKey; let profilePDA: PublicKey; let testProfilePDA: anchor.web3.PublicKey; let treeConfigPDA: PublicKey; @@ -51,16 +54,19 @@ describe("Connection Compression", async () => { // Set up a user const randomHash = randomBytes(32); - const userTx = gpl_core.methods.createUser(randomHash).accounts({ - authority: payer.publicKey, - }); - userPDA = (await userTx.pubkeys()).user; - await userTx.signers([payer]).rpc(); + + const gumTld = await createGumTld(); // Set up a profile + const profileMetdataUri = "https://example.com"; + const screenName = await createGumDomain( + gumTld, + faker.internet.userName(), + payer + ); const profileTx = gpl_core.methods - .createProfile("Personal") - .accounts({ user: userPDA, authority: payer.publicKey }); + .createProfile(randomHash, profileMetdataUri) + .accounts({ authority: payer.publicKey, screenName }); profilePDA = (await profileTx.pubkeys()).profile; await profileTx.signers([payer]).rpc(); @@ -69,18 +75,20 @@ describe("Connection Compression", async () => { await airdrop(testUser.publicKey); const randomTestHash = randomBytes(32); - const createTestUser = gpl_core.methods - .createUser(randomTestHash) - .accounts({ authority: testUser.publicKey }); - const testUserPubKeys = await createTestUser.pubkeys(); - let testUserPDA = testUserPubKeys.user as anchor.web3.PublicKey; - - await createTestUser.signers([testUser]).rpc(); // Create a testProfile + const testProfileMetdataUri = "https://example.com"; + const testScreenName = await createGumDomain( + gumTld, + faker.internet.userName(), + testUser + ); const testProfile = gpl_core.methods - .createProfile("Personal") - .accounts({ user: testUserPDA, authority: testUser.publicKey }); + .createProfile(randomTestHash, testProfileMetdataUri) + .accounts({ + authority: testUser.publicKey, + screenName: testScreenName, + }); const testProfilePubKeys = await testProfile.pubkeys(); testProfilePDA = testProfilePubKeys.profile as anchor.web3.PublicKey; @@ -93,7 +101,6 @@ describe("Connection Compression", async () => { await gpl_compression.methods .createCompressedConnection() .accounts({ - user: userPDA, fromProfile: profilePDA, toProfile: testProfilePDA, treeConfig: treeConfigPDA, @@ -137,7 +144,6 @@ describe("Connection Compression", async () => { await gpl_compression.methods .createCompressedConnection() .accounts({ - user: userPDA, fromProfile: profilePDA, toProfile: testProfilePDA, treeConfig: treeConfigPDA, @@ -182,7 +188,6 @@ describe("Connection Compression", async () => { await gpl_compression.methods .deleteCompressedConnection(proof.root, index) .accounts({ - user: userPDA, fromProfile: profilePDA, toProfile: testProfilePDA, treeConfig: treeConfigPDA, diff --git a/tests/gpl_compression/post.spec.ts b/tests/gpl_compression/post.spec.ts index cdde970..82e6cc1 100644 --- a/tests/gpl_compression/post.spec.ts +++ b/tests/gpl_compression/post.spec.ts @@ -7,6 +7,8 @@ import { setupTree, to_leaf, assert_tree, + createGumTld, + createGumDomain, } from "../utils/index"; import { @@ -18,16 +20,16 @@ import { import { Keypair, PublicKey } from "@solana/web3.js"; -import { expect } from "chai"; import randomBytes from "randombytes"; +import { faker } from "@faker-js/faker"; + anchor.setProvider(anchor.AnchorProvider.env()); const rpcConnection = anchor.getProvider().connection; describe("Post Compression", async () => { let payer: Keypair; let merkleTree: PublicKey; - let userPDA: PublicKey; let profilePDA: PublicKey; let treeConfigPDA: PublicKey; let offChainTree: MerkleTree; @@ -48,18 +50,21 @@ describe("Post Compression", async () => { treeConfigPDA = treeResult.treeConfigPDA; offChainTree = treeResult.offChainTree; - // Set up a user const randomHash = randomBytes(32); - const userTx = gpl_core.methods.createUser(randomHash).accounts({ - authority: payer.publicKey, - }); - userPDA = (await userTx.pubkeys()).user; - await userTx.signers([payer]).rpc(); + + const gumTld = await createGumTld(); // Set up a profile + const profileMetadataUri = "https://example.com"; + + const screenName = await createGumDomain( + gumTld, + faker.internet.userName(), + payer + ); const profileTx = gpl_core.methods - .createProfile("Personal") - .accounts({ user: userPDA, authority: payer.publicKey }); + .createProfile(randomHash, profileMetadataUri) + .accounts({ authority: payer.publicKey, screenName }); profilePDA = (await profileTx.pubkeys()).profile; await profileTx.signers([payer]).rpc(); }); @@ -71,7 +76,6 @@ describe("Post Compression", async () => { await gpl_compression.methods .createCompressedPost(metadataUri, randomHash) .accounts({ - user: userPDA, profile: profilePDA, treeConfig: treeConfigPDA, merkleTree, @@ -115,7 +119,6 @@ describe("Post Compression", async () => { await gpl_compression.methods .createCompressedPost(metadataUri, randomHash) .accounts({ - user: userPDA, profile: profilePDA, treeConfig: treeConfigPDA, merkleTree, @@ -162,7 +165,6 @@ describe("Post Compression", async () => { index ) .accounts({ - user: userPDA, profile: profilePDA, treeConfig: treeConfigPDA, merkleTree, @@ -206,7 +208,6 @@ describe("Post Compression", async () => { //@ts-ignore .createCompressedPost(metadataUri, randomHash) .accounts({ - user: userPDA, profile: profilePDA, treeConfig: treeConfigPDA, merkleTree, @@ -252,7 +253,6 @@ describe("Post Compression", async () => { index ) .accounts({ - user: userPDA, profile: profilePDA, treeConfig: treeConfigPDA, merkleTree, diff --git a/tests/gpl_compression/reaction.spec.ts b/tests/gpl_compression/reaction.spec.ts index 034d533..78a1cac 100644 --- a/tests/gpl_compression/reaction.spec.ts +++ b/tests/gpl_compression/reaction.spec.ts @@ -6,6 +6,8 @@ import { gpl_compression, setupTree, to_leaf, + createGumTld, + createGumDomain, } from "../utils/index"; import { @@ -20,6 +22,8 @@ import { Keypair, PublicKey } from "@solana/web3.js"; import { expect } from "chai"; import randomBytes from "randombytes"; +import { faker } from "@faker-js/faker"; + anchor.setProvider(anchor.AnchorProvider.env()); const rpcConnection = anchor.getProvider().connection; @@ -29,10 +33,9 @@ describe("Reaction Compression", async () => { let treeConfigPDA: PublicKey; let offChainTree: MerkleTree; - let userPDA: PublicKey; let profilePDA: PublicKey; let postPDA: PublicKey; - let reactionPDA: PublicKey; + let emoji = "👍"; beforeEach(async () => { // Setup a new keypair and airdrop some SOL @@ -51,18 +54,18 @@ describe("Reaction Compression", async () => { offChainTree = treeResult.offChainTree; const randomHash = randomBytes(32); - // @ts-ignore - const userTx = gpl_core.methods.createUser(randomHash).accounts({ - authority: payer.publicKey, - }); - const userPubKeys = await userTx.pubkeys(); - userPDA = userPubKeys.user as anchor.web3.PublicKey; - await userTx.signers([payer]).rpc(); // Create a profile + const profileMetdataUri = "https://example.com"; + const gumTld = await createGumTld(); + const screenName = await createGumDomain( + gumTld, + faker.internet.userName(), + payer + ); const profileTx = gpl_core.methods - .createProfile("Personal") - .accounts({ user: userPDA, authority: payer.publicKey }); + .createProfile(randomHash, profileMetdataUri) + .accounts({ authority: payer.publicKey, screenName }); const profilePubKeys = await profileTx.pubkeys(); profilePDA = profilePubKeys.profile as anchor.web3.PublicKey; await profileTx.signers([payer]).rpc(); @@ -74,7 +77,6 @@ describe("Reaction Compression", async () => { // @ts-ignore .createPost(metadataUri, postRandomHash) .accounts({ - user: userPDA, profile: profilePDA, authority: payer.publicKey, sessionToken: null, @@ -91,13 +93,12 @@ describe("Reaction Compression", async () => { .createCompressedReaction( //@ts-ignore postPDA, - "Haha", + emoji, postProof.root, postProof.leaf, 0 ) .accounts({ - user: userPDA, fromProfile: profilePDA, treeConfig: treeConfigPDA, merkleTree, @@ -120,7 +121,7 @@ describe("Reaction Compression", async () => { const reactionSeeds = [ Buffer.from("reaction"), - Buffer.from("Haha"), + Buffer.from(emoji), postPDA.toBuffer(), profilePDA.toBuffer(), ]; @@ -128,8 +129,7 @@ describe("Reaction Compression", async () => { const reaction = { fromProfile: profilePDA, toPost: postPDA, - // Weird anchor trick for passing enums - reactionType: { haha: {} }, + reactionType: emoji, }; const reactionLeaf = await to_leaf( @@ -149,13 +149,12 @@ describe("Reaction Compression", async () => { .createCompressedReaction( //@ts-ignore postPDA, - "Haha", + emoji, postProof.root, postProof.leaf, index ) .accounts({ - user: userPDA, fromProfile: profilePDA, treeConfig: treeConfigPDA, merkleTree, @@ -178,7 +177,7 @@ describe("Reaction Compression", async () => { const reactionSeeds = [ Buffer.from("reaction"), - Buffer.from("Haha"), + Buffer.from(emoji), postPDA.toBuffer(), profilePDA.toBuffer(), ]; @@ -186,8 +185,7 @@ describe("Reaction Compression", async () => { const reaction = { fromProfile: profilePDA, toPost: postPDA, - // Weird anchor trick for passing enums - reactionType: { haha: {} }, + reactionType: emoji, }; const reactionLeaf = await to_leaf( @@ -206,9 +204,8 @@ describe("Reaction Compression", async () => { await gpl_compression.methods // @ts-ignore - .deleteCompressedReaction(postPDA, "Haha", proof.root, index) + .deleteCompressedReaction(postPDA, emoji, proof.root, index) .accounts({ - user: userPDA, fromProfile: profilePDA, treeConfig: treeConfigPDA, merkleTree, diff --git a/tests/gpl_core/comment.spec.ts b/tests/gpl_core/comment.spec.ts index 9453de7..db876ce 100644 --- a/tests/gpl_core/comment.spec.ts +++ b/tests/gpl_core/comment.spec.ts @@ -3,7 +3,7 @@ import randombytes from "randombytes"; import { expect } from "chai"; import { sendAndConfirmTransaction } from "@solana/web3.js"; import { GplCore } from "../../target/types/gpl_core"; -import { new_session, airdrop } from "../utils"; +import { new_session, airdrop, createGumTld, createGumDomain } from "../utils"; const program = anchor.workspace.GplCore as anchor.Program; @@ -21,17 +21,15 @@ describe("Comment", async () => { let fromProfilePDA: anchor.web3.PublicKey; before(async () => { - // Create a user const randomHash = randombytes(32); - const userTx = program.methods.createUser(randomHash); - const userPubKeys = await userTx.pubkeys(); - userPDA = userPubKeys.user as anchor.web3.PublicKey; - await userTx.rpc(); + const gumTld = await createGumTld(); // Create a profile + const profileMetdataUri = "https://example.com"; + const screenName = await createGumDomain(gumTld, "foobarq3eqw"); const profileTx = program.methods - .createProfile("Personal") - .accounts({ user: userPDA }); + .createProfile(randomHash, profileMetdataUri) + .accounts({ screenName }); const profilePubKeys = await profileTx.pubkeys(); profilePDA = profilePubKeys.profile as anchor.web3.PublicKey; await profileTx.rpc(); @@ -41,7 +39,7 @@ describe("Comment", async () => { const metadataUri = "This is a test post"; const post = program.methods .createPost(metadataUri, postRandomHash) - .accounts({ user: userPDA, profile: profilePDA, sessionToken: null }); + .accounts({ profile: profilePDA, sessionToken: null }); const postPubKeys = await post.pubkeys(); postPDA = postPubKeys.post as anchor.web3.PublicKey; await post.rpc(); @@ -56,17 +54,19 @@ describe("Comment", async () => { // Create a test user pda const testUserRandomhash = randombytes(32); - const testUserTx = program.methods.createUser(testUserRandomhash).accounts({ - authority: testUserKeypair.publicKey, - }); - const testUserPubKeys = await testUserTx.pubkeys(); - testUserPDA = testUserPubKeys.user as anchor.web3.PublicKey; - await testUserTx.signers([testUserKeypair]).rpc(); + const testScreenName = await createGumDomain( + gumTld, + "goobarq3eqw", + testUserKeypair + ); // Create a from profile const fromProfileTx = program.methods - .createProfile("Personal") - .accounts({ user: testUserPDA, authority: testUserKeypair.publicKey }); + .createProfile(testUserRandomhash, profileMetdataUri) + .accounts({ + authority: testUserKeypair.publicKey, + screenName: testScreenName, + }); const fromProfilePubkeys = await fromProfileTx.pubkeys(); fromProfilePDA = fromProfilePubkeys.profile as anchor.web3.PublicKey; await fromProfileTx.signers([testUserKeypair]).rpc(); @@ -80,7 +80,6 @@ describe("Comment", async () => { .accounts({ replyTo: postPDA, profile: fromProfilePDA, - user: testUserPDA, authority: testUserKeypair.publicKey, sessionToken: null, }); @@ -138,7 +137,6 @@ describe("Comment", async () => { .accounts({ replyTo: postPDA, profile: fromProfilePDA, - user: testUserPDA, authority: sessionKeypair.publicKey, sessionToken: sessionToken, }); diff --git a/tests/gpl_core/connection.spec.ts b/tests/gpl_core/connection.spec.ts index fb9fb6f..7f1b681 100644 --- a/tests/gpl_core/connection.spec.ts +++ b/tests/gpl_core/connection.spec.ts @@ -5,6 +5,7 @@ import { airdrop, new_session } from "../utils"; import { expect } from "chai"; import { sendAndConfirmTransaction } from "@solana/web3.js"; import { GplCore } from "../../target/types/gpl_core"; +import { createGumDomain, createGumTld } from "../utils"; const program = anchor.workspace.GplCore as anchor.Program; const provider = anchor.getProvider(); @@ -16,8 +17,6 @@ describe("Connection", async () => { let testUser: anchor.web3.Keypair; let feePayer: anchor.web3.Keypair; let testUserWallet: NodeWallet; - let userPDA: anchor.web3.PublicKey; - let testUserPDA: anchor.web3.PublicKey; let profilePDA: anchor.web3.PublicKey; let testProfilePDA: anchor.web3.PublicKey; let connectionPDA: anchor.web3.PublicKey; @@ -29,15 +28,15 @@ describe("Connection", async () => { ); // Create a user const randomHash = randombytes(32); - const userTx = program.methods.createUser(randomHash); - const userPubKeys = await userTx.pubkeys(); - userPDA = userPubKeys.user as anchor.web3.PublicKey; - await userTx.rpc(); + + const gumTld = await createGumTld(); + const screenName = await createGumDomain(gumTld, "foobar"); // Create a profile + const profileMetdataUri = "https://example.com"; const profileTx = program.methods - .createProfile("Personal") - .accounts({ user: userPDA }); + .createProfile(randomHash, profileMetdataUri) + .accounts({ screenName }); const profilePubKeys = await profileTx.pubkeys(); profilePDA = profilePubKeys.profile as anchor.web3.PublicKey; await profileTx.rpc(); @@ -51,28 +50,17 @@ describe("Connection", async () => { feePayer = anchor.web3.Keypair.generate(); await airdrop(feePayer.publicKey); - const randomTestHash = randombytes(32); - const createTestUser = program.methods - .createUser(randomTestHash) - .accounts({ payer: testUser.publicKey, authority: testUser.publicKey }); - const testUserPubKeys = await createTestUser.pubkeys(); - testUserPDA = testUserPubKeys.user as anchor.web3.PublicKey; - const testUserTx = await createTestUser.transaction(); - testUserTx.recentBlockhash = ( - await rpcConnection.getLatestBlockhash() - ).blockhash; - testUserTx.feePayer = testUser.publicKey; - const signedTestUserTransaction = await testUserWallet.signTransaction( - testUserTx - ); - await sendAndConfirmTransaction(rpcConnection, signedTestUserTransaction, [ - testUser, - ]); - // Create a testProfile + const testProfileMetdataUri = "https://example.com"; + const testRandomHash = randombytes(32); + const testScreenName = await createGumDomain(gumTld, "test", testUser); const testProfile = program.methods - .createProfile("Personal") - .accounts({ payer: testUser.publicKey, user: testUserPDA, authority: testUser.publicKey }); + .createProfile(testRandomHash, testProfileMetdataUri) + .accounts({ + payer: testUser.publicKey, + authority: testUser.publicKey, + screenName: testScreenName, + }); const testProfilePubKeys = await testProfile.pubkeys(); testProfilePDA = testProfilePubKeys.profile as anchor.web3.PublicKey; const testProfileTx = await testProfile.transaction(); @@ -92,7 +80,6 @@ describe("Connection", async () => { const connection = program.methods.createConnection().accounts({ fromProfile: profilePDA, toProfile: testProfilePDA, - user: userPDA, sessionToken: null, }); const pubKeys = await connection.pubkeys(); @@ -115,7 +102,6 @@ describe("Connection", async () => { fromProfile: profilePDA, toProfile: testProfilePDA, connection: connectionPDA, - user: userPDA, sessionToken: null, // @ts-ignore refundReceiver: provider.wallet.publicKey, @@ -133,15 +119,12 @@ describe("Connection", async () => { }); it("should create a connection when a seperate fee payer is specified", async () => { - const createConnection = program.methods - .createConnection() - .accounts({ - payer: feePayer.publicKey, - fromProfile: profilePDA, - toProfile: testProfilePDA, - user: userPDA, - sessionToken: null, - }); + const createConnection = program.methods.createConnection().accounts({ + payer: feePayer.publicKey, + fromProfile: profilePDA, + toProfile: testProfilePDA, + sessionToken: null, + }); const pubKeys = await createConnection.pubkeys(); connectionPDA = pubKeys.connection as anchor.web3.PublicKey; await createConnection.signers([feePayer]).rpc(); @@ -157,15 +140,17 @@ describe("Connection", async () => { ); // Cleanup for next tests - await program.methods.deleteConnection().accounts({ - fromProfile: profilePDA, - toProfile: testProfilePDA, - connection: connectionPDA, - user: userPDA, - sessionToken: null, - // @ts-ignore - refundReceiver: provider.wallet.publicKey, - }).rpc(); + await program.methods + .deleteConnection() + .accounts({ + fromProfile: profilePDA, + toProfile: testProfilePDA, + connection: connectionPDA, + sessionToken: null, + // @ts-ignore + refundReceiver: provider.wallet.publicKey, + }) + .rpc(); }); describe("Connection with session token", async () => { @@ -186,7 +171,6 @@ describe("Connection", async () => { const connection = program.methods.createConnection().accounts({ fromProfile: profilePDA, toProfile: testProfilePDA, - user: userPDA, sessionToken: sessionToken, authority: sessionKeypair.publicKey, }); @@ -209,7 +193,6 @@ describe("Connection", async () => { fromProfile: profilePDA, toProfile: testProfilePDA, connection: connectionPDA, - user: userPDA, sessionToken: sessionToken, authority: sessionKeypair.publicKey, // @ts-ignore diff --git a/tests/gpl_core/post.spec.ts b/tests/gpl_core/post.spec.ts index eacf467..08212ef 100644 --- a/tests/gpl_core/post.spec.ts +++ b/tests/gpl_core/post.spec.ts @@ -2,6 +2,7 @@ import * as anchor from "@project-serum/anchor"; import randombytes from "randombytes"; import { expect } from "chai"; import { GplCore } from "../../target/types/gpl_core"; +import { createGumDomain, createGumTld } from "../utils"; import { airdrop, new_session } from "../utils"; import { sendAndConfirmTransaction } from "@solana/web3.js"; @@ -12,23 +13,20 @@ anchor.setProvider(anchor.AnchorProvider.env()); const provider = anchor.getProvider(); describe("Post", async () => { - let userPDA: anchor.web3.PublicKey; let profilePDA: anchor.web3.PublicKey; let postPDA: anchor.web3.PublicKey; let feePayer: anchor.web3.Keypair; before(async () => { - // Create a user const randomHash = randombytes(32); - const userTx = program.methods.createUser(randomHash); - const userPubKeys = await userTx.pubkeys(); - userPDA = userPubKeys.user as anchor.web3.PublicKey; - await userTx.rpc(); + const gumTld = await createGumTld(); // Create a profile + const profileMetdataUri = "https://example.com"; + const screenName = await createGumDomain(gumTld, "sdfsdfdsfgsdgsd"); const profileTx = program.methods - .createProfile("Personal") - .accounts({ user: userPDA }); + .createProfile(randomHash, profileMetdataUri) + .accounts({ screenName }); const profilePubKeys = await profileTx.pubkeys(); profilePDA = profilePubKeys.profile as anchor.web3.PublicKey; await profileTx.rpc(); @@ -43,7 +41,7 @@ describe("Post", async () => { const metadataUri = "This is a test post"; const post = program.methods .createPost(metadataUri, randomHash) - .accounts({ user: userPDA, profile: profilePDA, sessionToken: null }); + .accounts({ profile: profilePDA, sessionToken: null }); const postPubKeys = await post.pubkeys(); postPDA = postPubKeys.post as anchor.web3.PublicKey; await post.rpc(); @@ -55,7 +53,6 @@ describe("Post", async () => { it("should update a post", async () => { const metadataUri = "This is an updated test post"; const post = program.methods.updatePost(metadataUri).accounts({ - user: userPDA, profile: profilePDA, post: postPDA, sessionToken: null, @@ -68,7 +65,6 @@ describe("Post", async () => { it("should delete a post", async () => { const post = program.methods.deletePost().accounts({ - user: userPDA, profile: profilePDA, post: postPDA, sessionToken: null, @@ -90,7 +86,11 @@ describe("Post", async () => { const metadataUri = "This is a test post"; const createPost = program.methods .createPost(metadataUri, randomHash) - .accounts({ payer: feePayer.publicKey, user: userPDA, profile: profilePDA, sessionToken: null }); + .accounts({ + payer: feePayer.publicKey, + profile: profilePDA, + sessionToken: null, + }); const pubKeys = await createPost.pubkeys(); postPDA = pubKeys.post as anchor.web3.PublicKey; await createPost.signers([feePayer]).rpc(); @@ -119,29 +119,24 @@ describe("Post", async () => { randomUserWallet = new anchor.Wallet(randomUser); await airdrop(randomUser.publicKey); - // Create a user const randomHash = randombytes(32); - const userTx = program.methods - .createUser(randomHash) - .accounts({ payer: randomUser.publicKey, authority: randomUser.publicKey }); - const userPubKeys = await userTx.pubkeys(); - randomUserPDA = userPubKeys.user; - const tx = await userTx.transaction(); - tx.recentBlockhash = (await rpcConnection.getRecentBlockhash()).blockhash; - tx.feePayer = randomUser.publicKey; - const signedTestUserTransaction = await randomUserWallet.signTransaction( - tx - ); - await sendAndConfirmTransaction( - rpcConnection, - signedTestUserTransaction, - [randomUser] - ); + const gumTld = await createGumTld(); + // Create a profile + const profileMetdataUri = "https://example.com"; + const screenName = await createGumDomain( + gumTld, + "testscreename", + randomUser + ); // Create a profile const testProfile = program.methods - .createProfile("Personal") - .accounts({ payer: randomUser.publicKey, user: randomUserPDA, authority: randomUser.publicKey }); + .createProfile(randomHash, profileMetdataUri) + .accounts({ + payer: randomUser.publicKey, + authority: randomUser.publicKey, + screenName, + }); const testProfilePubKeys = await testProfile.pubkeys(); randomProfilePDA = testProfilePubKeys.profile as anchor.web3.PublicKey; const testProfileTx = await testProfile.transaction(); @@ -172,7 +167,6 @@ describe("Post", async () => { const post = program.methods .createPost(metadataUri, randomHash) .accounts({ - user: userPDA, profile: profilePDA, sessionToken: sessionToken, authority: sessionKeypair.publicKey, @@ -191,7 +185,6 @@ describe("Post", async () => { const post = program.methods .createPost(metadataUri, randomHash) .accounts({ - user: randomUserPDA, profile: randomProfilePDA, sessionToken: sessionToken, authority: randomUser.publicKey, @@ -212,7 +205,6 @@ describe("Post", async () => { const post = program.methods .createPost(metadataUri, randomHash) .accounts({ - user: randomUserPDA, profile: randomProfilePDA, sessionToken: sessionToken, authority: randomUser.publicKey, @@ -230,7 +222,6 @@ describe("Post", async () => { it("should update a post", async () => { const metadataUri = "This is an updated test post"; const post = program.methods.updatePost(metadataUri).accounts({ - user: userPDA, profile: profilePDA, post: postPDA, sessionToken: sessionToken, @@ -244,7 +235,6 @@ describe("Post", async () => { it("should delete a post", async () => { const post = program.methods.deletePost().accounts({ - user: userPDA, profile: profilePDA, post: postPDA, sessionToken: sessionToken, diff --git a/tests/gpl_core/profile.spec.ts b/tests/gpl_core/profile.spec.ts index 02f7154..54bc928 100644 --- a/tests/gpl_core/profile.spec.ts +++ b/tests/gpl_core/profile.spec.ts @@ -2,48 +2,43 @@ import * as anchor from "@project-serum/anchor"; import randombytes from "randombytes"; import { expect } from "chai"; import { GplCore } from "../../target/types/gpl_core"; -import { airdrop } from "../utils"; +import { airdrop, createGumDomain, createGumTld } from "../utils"; const program = anchor.workspace.GplCore as anchor.Program; anchor.setProvider(anchor.AnchorProvider.env()); describe("Profile", async () => { - let userPDA: anchor.web3.PublicKey; let profilePDA: anchor.web3.PublicKey; + let gumTld: anchor.web3.PublicKey; let feePayer: anchor.web3.Keypair; before(async () => { - // Create a user - const randomHash = randombytes(32); - const tx = program.methods.createUser(randomHash); - const pubKeys = await tx.pubkeys(); - userPDA = pubKeys.user as anchor.web3.PublicKey; - await tx.rpc(); - - // Create fee payer keypair + // Create gum tld + gumTld = await createGumTld(); feePayer = anchor.web3.Keypair.generate(); await airdrop(feePayer.publicKey); }); it("should create a profile", async () => { + const profileMetdataUri = "https://example.com"; + const screenName = await createGumDomain(gumTld, "foobar123123"); + const randomHash = randombytes(32); + const tx = program.methods - .createProfile("Personal") - .accounts({ user: userPDA }); + .createProfile(randomHash, profileMetdataUri) + .accounts({ screenName }); const pubKeys = await tx.pubkeys(); profilePDA = pubKeys.profile as anchor.web3.PublicKey; await tx.rpc(); const profileAccount = await program.account.profile.fetch(profilePDA); - expect(profileAccount.user.toString()).is.equal(userPDA.toString()); - expect(profileAccount.namespace.toString()).is.equal( - { personal: {} }.toString() - ); + expect(profileAccount.metadataUri).to.equal(profileMetdataUri); }); it("should delete a profile", async () => { const tx = program.methods .deleteProfile() - .accounts({ user: userPDA, profile: profilePDA }); + .accounts({ profile: profilePDA }); await tx.rpc(); try { await program.account.profile.fetch(profilePDA); @@ -56,16 +51,16 @@ describe("Profile", async () => { }); it("should create a profile when a seperate fee payer is specified", async () => { + const randomHash = randombytes(32); + const profileMetdataUri = "https://example.com"; + const screenName = await createGumDomain(gumTld, "dfgdsfgsdfgsrd"); const tx = program.methods - .createProfile("Personal") - .accounts({ payer: feePayer.publicKey, user: userPDA }); + .createProfile(randomHash, profileMetdataUri) + .accounts({ payer: feePayer.publicKey, screenName }); const pubKeys = await tx.pubkeys(); profilePDA = pubKeys.profile as anchor.web3.PublicKey; await tx.signers([feePayer]).rpc(); const profileAccount = await program.account.profile.fetch(profilePDA); - expect(profileAccount.user.toString()).is.equal(userPDA.toString()); - expect(profileAccount.namespace.toString()).is.equal( - { personal: {} }.toString() - ); + expect(profileAccount.metadataUri).to.equal(profileMetdataUri); }); }); diff --git a/tests/gpl_core/profile_metadata.spec.ts b/tests/gpl_core/profile_metadata.spec.ts deleted file mode 100644 index e9e6c8a..0000000 --- a/tests/gpl_core/profile_metadata.spec.ts +++ /dev/null @@ -1,110 +0,0 @@ -import * as anchor from "@project-serum/anchor"; -import randombytes from "randombytes"; -import { expect } from "chai"; -import { GplCore } from "../../target/types/gpl_core"; -import { airdrop } from "../utils"; - -const program = anchor.workspace.GplCore as anchor.Program; - -anchor.setProvider(anchor.AnchorProvider.env()); - -describe("Profile Metadata", async () => { - let userPDA: anchor.web3.PublicKey; - let profilePDA: anchor.web3.PublicKey; - let profileMetadataPDA: anchor.web3.PublicKey; - let feePayer: anchor.web3.Keypair; - - before(async () => { - // Create a user - const randomHash = randombytes(32); - const userTx = program.methods.createUser(randomHash); - const userPubKeys = await userTx.pubkeys(); - userPDA = userPubKeys.user as anchor.web3.PublicKey; - await userTx.rpc(); - - // Create a profile - const profileTx = program.methods - .createProfile("Personal") - .accounts({ user: userPDA }); - const profilePubKeys = await profileTx.pubkeys(); - profilePDA = profilePubKeys.profile as anchor.web3.PublicKey; - await profileTx.rpc(); - - // Create fee payer keypair - feePayer = anchor.web3.Keypair.generate(); - await airdrop(feePayer.publicKey); - }); - - it("should create a profile metadata", async () => { - const randomHash = randombytes(32); - const metadataUri = "https://example.com"; - const profileMetadata = program.methods - .createProfileMetadata(metadataUri) - .accounts({ user: userPDA, profile: profilePDA }); - const profileMetadataPubKeys = await profileMetadata.pubkeys(); - profileMetadataPDA = - profileMetadataPubKeys.profileMetadata as anchor.web3.PublicKey; - await profileMetadata.rpc(); - const profileMetadataAccount = await program.account.profileMetadata.fetch( - profileMetadataPDA - ); - expect(profileMetadataAccount.metadataUri).is.equal(metadataUri); - expect(profileMetadataAccount.profile.toString()).is.equal( - profilePDA.toString() - ); - }); - - it("should update a profile metadata", async () => { - const metadataUri = "https://example.com/updated"; - const profileMetadata = program.methods - .updateProfileMetadata(metadataUri) - .accounts({ - user: userPDA, - profile: profilePDA, - profileMetadata: profileMetadataPDA, - }); - await profileMetadata.rpc(); - const profileMetadataAccount = await program.account.profileMetadata.fetch( - profileMetadataPDA - ); - expect(profileMetadataAccount.metadataUri).is.equal(metadataUri); - expect(profileMetadataAccount.profile.toString()).is.equal( - profilePDA.toString() - ); - }); - - it("should delete a profile metadata", async () => { - const profileMetadata = program.methods.deleteProfileMetadata().accounts({ - user: userPDA, - profile: profilePDA, - profileMetadata: profileMetadataPDA, - }); - await profileMetadata.rpc(); - try { - await program.account.profileMetadata.fetch(profileMetadataPDA); - } catch (error: any) { - expect(error).to.be.an("error"); - expect(error.toString()).to.contain( - `Account does not exist or has no data ${profileMetadataPDA.toString()}` - ); - } - }); - - it("should create a profile metadata when a seperate fee payer is specified", async () => { - const metadataUri = "https://example.com"; - const profileMetadata = program.methods - .createProfileMetadata(metadataUri) - .accounts({ payer: feePayer.publicKey, user: userPDA, profile: profilePDA }); - const profileMetadataPubKeys = await profileMetadata.pubkeys(); - profileMetadataPDA = - profileMetadataPubKeys.profileMetadata as anchor.web3.PublicKey; - await profileMetadata.signers([feePayer]).rpc(); - const profileMetadataAccount = await program.account.profileMetadata.fetch( - profileMetadataPDA - ); - expect(profileMetadataAccount.metadataUri).is.equal(metadataUri); - expect(profileMetadataAccount.profile.toString()).is.equal( - profilePDA.toString() - ); - }); -}); diff --git a/tests/gpl_core/reaction.spec.ts b/tests/gpl_core/reaction.spec.ts index 51608d9..592e8e5 100644 --- a/tests/gpl_core/reaction.spec.ts +++ b/tests/gpl_core/reaction.spec.ts @@ -2,7 +2,7 @@ import * as anchor from "@project-serum/anchor"; import randombytes from "randombytes"; import { expect } from "chai"; import { GplCore } from "../../target/types/gpl_core"; -import { airdrop, new_session } from "../utils"; +import { airdrop, new_session, createGumDomain, createGumTld } from "../utils"; const program = anchor.workspace.GplCore as anchor.Program; @@ -11,24 +11,23 @@ anchor.setProvider(anchor.AnchorProvider.env()); const provider = anchor.getProvider(); describe("Reaction", async () => { - let userPDA: anchor.web3.PublicKey; let profilePDA: anchor.web3.PublicKey; let postPDA: anchor.web3.PublicKey; let reactionPDA: anchor.web3.PublicKey; + let emoji = "👍"; let feePayer: anchor.web3.Keypair; before(async () => { // Create a user const randomHash = randombytes(32); - const userTx = program.methods.createUser(randomHash); - const userPubKeys = await userTx.pubkeys(); - userPDA = userPubKeys.user as anchor.web3.PublicKey; - await userTx.rpc(); + const gumTld = await createGumTld(); + const screenName = await createGumDomain(gumTld, "foobarasdfas"); // Create a profile + const profileMetdataUri = "https://example.com"; const profileTx = program.methods - .createProfile("Personal") - .accounts({ user: userPDA }); + .createProfile(randomHash, profileMetdataUri) + .accounts({ screenName }); const profilePubKeys = await profileTx.pubkeys(); profilePDA = profilePubKeys.profile as anchor.web3.PublicKey; await profileTx.rpc(); @@ -38,7 +37,7 @@ describe("Reaction", async () => { const metadataUri = "This is a test post"; const post = program.methods .createPost(metadataUri, postRandomHash) - .accounts({ user: userPDA, profile: profilePDA, sessionToken: null }); + .accounts({ profile: profilePDA, sessionToken: null }); const postPubKeys = await post.pubkeys(); postPDA = postPubKeys.post as anchor.web3.PublicKey; await post.rpc(); @@ -49,31 +48,25 @@ describe("Reaction", async () => { }); it("should create a reaction", async () => { - const reaction = program.methods.createReaction("Haha").accounts({ + const reaction = program.methods.createReaction(emoji).accounts({ toPost: postPDA, fromProfile: profilePDA, - user: userPDA, sessionToken: null, }); const reactionPubKeys = await reaction.pubkeys(); reactionPDA = reactionPubKeys.reaction as anchor.web3.PublicKey; await reaction.rpc(); - const reactionAccount = await program.account.reaction.fetch(reactionPDA); expect(reactionAccount.toPost.toBase58()).to.equal(postPDA.toBase58()); expect(reactionAccount.fromProfile.toBase58()).to.equal( profilePDA.toBase58() ); - expect(reactionAccount.reactionType.toString()).to.equal( - { haha: {} }.toString() - ); }); it("should delete a reaction", async () => { const reaction = program.methods.deleteReaction().accounts({ toPost: postPDA, fromProfile: profilePDA, - user: userPDA, reaction: reactionPDA, sessionToken: null, refundReceiver: provider.wallet.publicKey, @@ -91,11 +84,10 @@ describe("Reaction", async () => { }); it("should create a reaction when a seperate fee payer is specified", async () => { - const reaction = program.methods.createReaction("Haha").accounts({ + const reaction = program.methods.createReaction(emoji).accounts({ payer: feePayer.publicKey, toPost: postPDA, fromProfile: profilePDA, - user: userPDA, sessionToken: null, }); const reactionPubKeys = await reaction.pubkeys(); @@ -107,19 +99,18 @@ describe("Reaction", async () => { expect(reactionAccount.fromProfile.toBase58()).to.equal( profilePDA.toBase58() ); - expect(reactionAccount.reactionType.toString()).to.equal( - { haha: {} }.toString() - ); // Clean up for next tests - await program.methods.deleteReaction().accounts({ - toPost: postPDA, - fromProfile: profilePDA, - user: userPDA, - reaction: reactionPDA, - sessionToken: null, - refundReceiver: provider.wallet.publicKey, - }).rpc(); + await program.methods + .deleteReaction() + .accounts({ + toPost: postPDA, + fromProfile: profilePDA, + reaction: reactionPDA, + sessionToken: null, + refundReceiver: provider.wallet.publicKey, + }) + .rpc(); }); describe("Reaction with session token", async () => { @@ -140,7 +131,6 @@ describe("Reaction", async () => { const reaction = program.methods.createReaction("Haha").accounts({ toPost: postPDA, fromProfile: profilePDA, - user: userPDA, sessionToken: sessionToken, authority: sessionKeypair.publicKey, }); @@ -152,16 +142,12 @@ describe("Reaction", async () => { expect(reactionAccount.fromProfile.toBase58()).to.equal( profilePDA.toBase58() ); - expect(reactionAccount.reactionType.toString()).to.equal( - { haha: {} }.toString() - ); }); it("should delete a reaction", async () => { const reaction = program.methods.deleteReaction().accounts({ toPost: postPDA, fromProfile: profilePDA, - user: userPDA, reaction: reactionPDA, sessionToken: sessionToken, authority: sessionKeypair.publicKey, diff --git a/tests/gpl_core/user.spec.ts b/tests/gpl_core/user.spec.ts deleted file mode 100644 index 62aaf66..0000000 --- a/tests/gpl_core/user.spec.ts +++ /dev/null @@ -1,105 +0,0 @@ -import * as anchor from "@project-serum/anchor"; -import NodeWallet from "@project-serum/anchor/dist/cjs/nodewallet"; -import randombytes from "randombytes"; -import { airdrop } from "../utils"; -import { expect } from "chai"; -import { sendAndConfirmTransaction } from "@solana/web3.js"; -import { GplCore } from "../../target/types/gpl_core"; - -const program = anchor.workspace.GplCore as anchor.Program; - -anchor.setProvider(anchor.AnchorProvider.env()); -const user = (anchor.getProvider() as any).wallet.payer; - -describe("User", async () => { - let connection: anchor.web3.Connection; - let userPDA: anchor.web3.PublicKey; - let randomUser: anchor.web3.Keypair; - let feePayer: anchor.web3.Keypair; - - before(async () => { - randomUser = anchor.web3.Keypair.generate(); - await airdrop(randomUser.publicKey); - connection = new anchor.web3.Connection( - "http://localhost:8899", - "confirmed" - ); - - feePayer = anchor.web3.Keypair.generate(); - await airdrop(feePayer.publicKey); - connection = new anchor.web3.Connection( - "http://localhost:8899", - "confirmed" - ); - }); - - it("should create a user", async () => { - const randomHash = randombytes(32); - const tx = program.methods.createUser(randomHash); - const pubKeys = await tx.pubkeys(); - userPDA = pubKeys.user as anchor.web3.PublicKey; - await tx.rpc(); - const userAccount = await program.account.user.fetch(userPDA); - expect(userAccount.authority.toString()).is.equal( - user.publicKey.toString() - ); - }); - - it("should update a user", async () => { - const tx = program.methods - .updateUser() - .accounts({ user: userPDA, newAuthority: randomUser.publicKey }); - const pubKeys = await tx.pubkeys(); - const randomUserPDA = pubKeys.user as anchor.web3.PublicKey; - await tx.rpc(); - const userAccount = await program.account.user.fetch(randomUserPDA); - expect(userAccount.authority.toString()).is.equal( - randomUser.publicKey.toString() - ); - }); - - it("should delete a user", async () => { - const randomUserWallet = new NodeWallet(randomUser); - const tx = program.methods - .deleteUser() - .accounts({ user: userPDA, authority: randomUser.publicKey }); - const pubKeys = await tx.pubkeys(); - const randomUserPDA = pubKeys.user as anchor.web3.PublicKey; - const transaction = await tx.transaction(); - transaction.recentBlockhash = ( - await connection.getLatestBlockhash() - ).blockhash; - transaction.feePayer = randomUser.publicKey; - const signedTransaction = await randomUserWallet.signTransaction( - transaction - ); - await sendAndConfirmTransaction(connection, signedTransaction, [ - randomUser, - ]); - try { - await program.account.user.fetch(randomUserPDA); - } catch (error: any) { - expect(error).to.be.an("error"); - expect(error.toString()).to.contain( - `Account does not exist or has no data ${randomUserPDA.toString()}` - ); - } - }); - - it("should create a user when a seperate fee payer is specified", async () => { - const randomHash = randombytes(32); - const createUser = program.methods - .createUser(randomHash) - .accounts({ - payer: feePayer.publicKey, - authority: user.publicKey, - }); - const pubKeys = await createUser.pubkeys(); - userPDA = pubKeys.user as anchor.web3.PublicKey; - await createUser.signers([feePayer]).rpc(); - const userAccount = await program.account.user.fetch(userPDA); - expect(userAccount.authority.toString()).is.equal( - user.publicKey.toString() - ); - }); -}); diff --git a/tests/utils/index.ts b/tests/utils/index.ts index fac72fd..5864ad4 100644 --- a/tests/utils/index.ts +++ b/tests/utils/index.ts @@ -9,6 +9,7 @@ import { import { GplCompression } from "../../target/types/gpl_compression"; import { GplCore } from "../../target/types/gpl_core"; +import { GplNameservice } from "../../target/types/gpl_nameservice"; import { GplSession } from "../../target/types/gpl_session"; import pkg from "js-sha3"; @@ -30,6 +31,70 @@ export const gpl_core = anchor.workspace.GplCore as anchor.Program; export const gpl_compression = anchor.workspace .GplCompression as anchor.Program; +export const gpl_nameservice = anchor.workspace + .GplNameservice as anchor.Program; + +// keccak256 hash of "gum" +const gumTldHash = keccak_256("gum"); + +const [gumTld, _] = anchor.web3.PublicKey.findProgramAddressSync( + [ + Buffer.from("name_record"), + Buffer.from(gumTldHash, "hex"), + anchor.web3.PublicKey.default.toBuffer(), + ], + gpl_nameservice.programId +); + +export async function createGumTld(): Promise { + try { + await gpl_nameservice.account.nameRecord.fetch(gumTld); + } catch (error: any) { + await gpl_nameservice.methods + .createTld("gum") + .accounts({ + nameRecord: gumTld, + }) + .rpc(); + } + return gumTld; +} + +export async function createGumDomain( + gumTld: PublicKey, + domain: string, + owner?: Keypair +): Promise { + // keccak256 hash of domain + const domainHash = keccak_256(domain); + const [nameRecord, _] = await anchor.web3.PublicKey.findProgramAddress( + [ + Buffer.from("name_record"), + Buffer.from(domainHash, "hex"), + gumTld.toBuffer(), + ], + gpl_nameservice.programId + ); + + let signers: Keypair[] = []; + + if (owner !== undefined) { + signers.push(owner); + } + + await gpl_nameservice.methods + .createNameRecord(domain) + .accounts({ + domain: gumTld, + nameRecord, + // @ts-ignore + authority: owner?.publicKey || provider.wallet.publicKey, + }) + .signers(signers) + .rpc(); + + return nameRecord; +} export const gpl_session = anchor.workspace .GplSession as anchor.Program; diff --git a/yarn.lock b/yarn.lock index f72798c..a7af67b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,6 +9,11 @@ dependencies: regenerator-runtime "^0.13.11" +"@faker-js/faker@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@faker-js/faker/-/faker-7.6.0.tgz#9ea331766084288634a9247fcd8b84f16ff4ba07" + integrity sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw== + "@coral-xyz/borsh@^0.26.0": version "0.26.0" resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.26.0.tgz#d054f64536d824634969e74138f9f7c52bbbc0d5"