Compare commits

...
8 changed files with 297 additions and 61 deletions
+246 -24
View File
@@ -1,35 +1,257 @@
(ns legacy.status-im.communities.e2e
(:require [taoensso.timbre :as log]
(:require [promesa.core :as promesa]
[status-im.common.json-rpc.events :as rpc]
[status-im.constants :as constants]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
;;NOTE: ONLY FOR QA
(rf/defn create-closed-community
{:events [:fast-create-community/create-closed-community]}
[_]
{:json-rpc/call [{:method "wakuext_createClosedCommunity"
:params []
:js-response true
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to create closed community." {:error %})}]
:dispatch [:hide-bottom-sheet]})
(def one-stt-in-wei "1000000000000000000")
(def one-eth-in-wei "1000000000000000000")
(def ten-stt-in-wei "10000000000000000000")
(def stt-symbol "STT")
(def eth-symbol "ETH")
(def null-address "0x0000000000000000000000000000000000000000")
(defn- eth-token-criteria
[amount-in-wei]
{:contractAddresses {constants/ethereum-sepolia-chain-id null-address
constants/arbitrum-sepolia-chain-id null-address
constants/optimism-sepolia-chain-id null-address}
:type constants/community-token-type-erc20
:symbol "ETH"
:name "Ethereum"
:amountInWei amount-in-wei
:decimals 18})
(defn- stt-token-criteria
[amount-in-wei]
{:contractAddresses {constants/ethereum-sepolia-chain-id constants/sepolia-stt-contract-address}
:type constants/community-token-type-erc20
:symbol "STT"
:name "Status Test Token"
:amountInWei amount-in-wei
:decimals 18})
(def token-criteria
{stt-symbol stt-token-criteria
eth-symbol eth-token-criteria})
(def base-channel-permissions
[{:permission-type constants/community-token-permission-can-view-channel
:token-symbol stt-symbol
:amount one-stt-in-wei}
{:permission-type constants/community-token-permission-can-view-channel
:token-symbol eth-symbol
:amount one-eth-in-wei}
{:permission-type constants/community-token-permission-can-view-and-post-channel
:token-symbol stt-symbol
:amount one-stt-in-wei}
{:permission-type constants/community-token-permission-can-view-and-post-channel
:token-symbol eth-symbol
:amount one-eth-in-wei}])
(defn- channel-names->description
[channel-names]
(map #(hash-map :name %1
:permissions [%2])
channel-names
base-channel-permissions))
(def community-descriptions
{:open
{:community-name "Open community"
:membership constants/community-permissions-auto-accept
:pin-message-allowed false}
:closed
{:community-name "Closed community"
:membership constants/community-permissions-manual-accept
:pin-message-allowed true
:categories [{:category-name "Pets" :channels #{"Cats" "Dogs"}}
{:category-name "Household" :channels #{"Rules"}}]
:channel-list [{:name "Cats"} {:name "Dogs"} {:name "Rules"}]}
:token-gated
{:community-name "Token gated community"
:membership constants/community-permissions-auto-accept
:pin-message-allowed true
:community-permissions [{:amount-in-wei ten-stt-in-wei
:permission-type constants/community-token-permission-become-member
:token-symbol stt-symbol}]
:channel-list (channel-names->description ["Lions" "Birds" "Trees" "Flowers"])}
:snt-admin
{:community-name "SNT Admin Community"
:membership constants/community-permissions-auto-accept
:pin-message-allowed true
:community-permissions [{:amount-in-wei one-stt-in-wei
:permission-type constants/community-token-permission-become-admin
:token-symbol stt-symbol}]
:channel-list (channel-names->description ["Sounds" "Colors" "Books" "Sports"])}
:admin-and-member
{:community-name "Admin and Member"
:membership constants/community-permissions-auto-accept
:pin-message-allowed true
:community-permissions [{:amount-in-wei one-stt-in-wei
:permission-type constants/community-token-permission-become-member
:token-symbol stt-symbol}
{:amount-in-wei one-eth-in-wei
:permission-type constants/community-token-permission-become-admin
:token-symbol eth-symbol}]
:channel-list (channel-names->description ["Party" "Birthday" "Travel" "Cars"])}})
(defn- js-messenger-response->community-id
[response]
(-> response .-communities first .-id))
(defn- js-messenger-response->channel-id
[channel-name response]
(->> response
.-communities
first
.-chats
js->clj
vals
(some #(when (= channel-name (get % "name")) (get % "id")))))
(defn- channel-token-criteria->request
[community-id channel-id {:keys [token-symbol amount]}]
(fn []
(rpc/call
{:method "wakuext_createCommunityTokenPermissionV2"
:js-response true
:params [{:communityID community-id
:type constants/community-token-permission-become-member
:chatIds [channel-id]
:tokenCriteria [((token-criteria token-symbol) amount)]}]})))
(defn- channel-token-criteria->requests
[community-id channel-id tokens]
(let [keep-fn (partial channel-token-criteria->request community-id channel-id)]
(keep keep-fn tokens)))
(defn- create-community-channel!
[channel community-id]
(->
(rpc/call
{:method "wakuext_createCommunityChannel"
:js-response true
:params [{:name (:name channel)
:communityId community-id
:description (:name channel)}]})
(.then (fn [response]
(if (:permissions channel)
(let [channel-id (js-messenger-response->channel-id (:name channel) response)]
(apply
promesa/chain
(promesa/resolved nil)
(channel-token-criteria->requests community-id channel-id (:permissions channel))))
response)))
(.catch #(log/error "failed to create token gated community channel."
{:error %
:channel-name (:name channel)}))))
(defn- create-category!
[response {:keys [category-name channels]}]
(let [community-id (js-messenger-response->community-id response)
channel-ids (map #(js-messenger-response->channel-id % response)
channels)]
(rpc/call
{:method "wakuext_createCommunityCategory"
:js-response true
:params [{:communityId community-id
:categoryName category-name
:chatIds channel-ids}]})))
(defn- create-community!
[community-name membership pin-message-allowed]
(rpc/call
{:method "wakuext_createCommunity"
:js-response true
:params [{:name community-name
:description community-name
:color "#887af9"
:historyArchiveSupportEnabled true
:membership membership
:pinMessageAllMembersEnabled pin-message-allowed}]}))
(defn- create-token-gated-permission!
[{:keys [token-symbol permission-type amount-in-wei]} community-id]
(rpc/call
{:method "wakuext_createCommunityTokenPermissionV2"
:js-response true
:params [{:communityId community-id
:type permission-type
:tokenCriteria [((token-criteria token-symbol) amount-in-wei)]}]}))
(def passthrough [identity])
(defn- create-community-from-description
[{:keys [community-name
membership
community-permissions
pin-message-allowed
categories
channel-list]}]
(let [create-community-permissions-fn (if (seq community-permissions)
(map
(fn [permission]
(fn [response]
(create-token-gated-permission!
permission
(js-messenger-response->community-id response))))
community-permissions)
passthrough)
create-channels-fn (if (seq channel-list)
(map
(fn [channel]
(fn [response]
(create-community-channel!
channel
(js-messenger-response->community-id response))))
channel-list)
passthrough)
create-categories-fn (if (seq categories)
(map
(fn [category]
(fn [messenger-response]
(create-category! messenger-response category)))
categories)
passthrough)]
(as-> (create-community! community-name membership pin-message-allowed) $
(apply promesa/chain $ create-community-permissions-fn)
(apply promesa/chain $ create-channels-fn)
(apply promesa/chain $ create-categories-fn)
(promesa/then $ #(rf/dispatch [:hide-bottom-sheet]))
(promesa/catch $ #(log/error "failed to create community e2e" {:error %})))))
(rf/defn create-open-community
{:events [:fast-create-community/create-open-community]}
{:events [:e2e/create-open-community]}
[_]
{:json-rpc/call [{:method "wakuext_createOpenCommunity"
:params []
:js-response true
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to create open community." {:error %})}]
:dispatch [:hide-bottom-sheet]})
(create-community-from-description (community-descriptions :open))
nil)
(rf/defn create-closed-community
{:events [:e2e/create-closed-community]}
[_]
(create-community-from-description (community-descriptions :closed))
nil)
(rf/defn create-token-gated-community
{:events [:fast-create-community/create-token-gated-community]}
{:events [:e2e/create-token-gated-community]}
[_]
{:json-rpc/call [{:method "wakuext_createTokenGatedCommunity"
:params []
:js-response true
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to create token gated community." {:error %})}]
:dispatch [:hide-bottom-sheet]})
(create-community-from-description (community-descriptions :token-gated))
nil)
(rf/defn snt-admin-community
{:events [:e2e/create-snt-admin-community]}
[_]
(create-community-from-description (community-descriptions :snt-admin))
nil)
(rf/defn admin-and-member-community
{:events [:e2e/create-admin-and-member-community]}
[_]
(create-community-from-description (community-descriptions :admin-and-member))
nil)
+18 -16
View File
@@ -2,6 +2,7 @@
(:require
[clojure.string :as string]
[native-module.core :as native-module]
[promesa.core :as promesa]
[re-frame.core :as re-frame]
[react-native.background-timer :as background-timer]
[taoensso.timbre :as log]
@@ -30,6 +31,14 @@
updated-delay)))
on-error))
(defn- handle-rpc-response
[callback deferred promise-resolution-fn result]
(when callback
(if (vector? callback)
(rf/dispatch (conj callback result))
(callback result)))
(promise-resolution-fn deferred result))
(defn call
"Call private RPC endpoint.
@@ -57,7 +66,8 @@
will be used.
"
[{:keys [method params on-success on-error js-response] :as arg}]
(let [params (or params [])
(let [deferred (promesa/deferred)
params (or params [])
on-error (or on-error
(on-error-retry call arg)
#(log/warn :json-rpc/error method :error % :params params))]
@@ -68,23 +78,15 @@
:params params})
(fn [raw-response]
(if (string/blank? raw-response)
(let [error {:message "Blank response"}]
(if (vector? on-error)
(rf/dispatch (conj on-error error))
(on-error error)))
(handle-rpc-response on-error deferred promesa/reject! {:message "Blank response"})
(let [^js response-js (transforms/json->js raw-response)]
(if-let [error (.-error response-js)]
(let [error (transforms/js->clj error)]
(if (vector? on-error)
(rf/dispatch (conj on-error error))
(on-error error)))
(when on-success
(let [result (if js-response
(.-result response-js)
(transforms/js->clj (.-result response-js)))]
(if (vector? on-success)
(rf/dispatch (conj on-success result))
(on-success result)))))))))))
(handle-rpc-response on-error deferred promesa/reject! (transforms/js->clj error))
(let [result (if js-response
(.-result response-js)
(transforms/js->clj (.-result response-js)))]
(handle-rpc-response on-success deferred promesa/resolve! result)))))))
deferred))
(re-frame/reg-fx
:json-rpc/call
+5
View File
@@ -71,6 +71,9 @@
(def ^:const timeline-chat-type 5)
(def ^:const community-chat-type 6)
(def ^:const community-permissions-auto-accept 1)
(def ^:const community-permissions-manual-accept 3)
(def ^:const contact-request-message-state-none 0)
(def ^:const contact-request-message-state-pending 1)
(def ^:const contact-request-message-state-accepted 2)
@@ -168,6 +171,8 @@
(def ^:const community-token-type-erc20 1)
(def ^:const community-token-type-erc721 2)
(def ^:const sepolia-stt-contract-address "0xe452027cdef746c7cd3db31cb700428b16cd8e51")
;; Community rules for joining
(def ^:const community-rule-ens-only "ens-only")
@@ -7,15 +7,22 @@
[]
[quo/action-drawer
[[{:icon :i/communities
:accessibility-label :create-closed-community
:label "Create closed community (only for testing)"
:on-press #(rf/dispatch [:fast-create-community/create-closed-community])}
{:icon :i/communities
:accessibility-label :create-open-community
:label "Create open community (only for testing)"
:on-press #(rf/dispatch [:fast-create-community/create-open-community])}
:label "Create Open community (only for testing)"
:on-press #(rf/dispatch [:e2e/create-open-community])}
{:icon :i/communities
:accessibility-label :create-closed-community
:label "Create Closed community (only for testing)"
:on-press #(rf/dispatch [:e2e/create-closed-community])}
{:icon :i/communities
:accessibility-label :create-admin-and-member-community
:label "Create Admin and Member community (only for testing)"
:on-press #(rf/dispatch [:e2e/create-admin-and-member-community])}
{:icon :i/communities
:accessibility-label :create-snt-admin-community
:label "Create SNT Admin community (only for testing)"
:on-press #(rf/dispatch [:e2e/create-snt-admin-community])}
{:icon :i/communities
:accessibility-label :create-token-gated-community
:label "Create token-gated community (only for testing)"
:on-press #(rf/dispatch
[:fast-create-community/create-token-gated-community])}]]])
:label "Create Token Gated community (only for testing)"
:on-press #(rf/dispatch [:e2e/create-token-gated-community])}]]])
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v0.179.3",
"commit-sha1": "b744ff4386751bd3e7cb8e30164678a8d557fbc2",
"src-sha256": "1yj76khas4g8xbgp2ymr1hwga662hsjmzpgb95x34vl42hdpirns"
"version": "chore/community-channel-endpoint",
"commit-sha1": "b710fa3e2e661973d5a5636868b8af0fa1de807d",
"src-sha256": "05pcda0sms16qs5dygmcwk9z3acxvfgkfjh5p4ybkh6q9cwwddwp"
}
@@ -268,7 +268,7 @@ class TestActivityMultipleDevicePR(MultipleSharedDeviceTestCase):
self.home_1.just_fyi("Open community to message")
self.home_1.communities_tab.click()
self.community_name = "open community"
self.community_name = "Open community"
self.channel_name = 'general'
self.home_1.create_community(community_type="open")
self.channel_1 = self.home_1.get_to_community_channel_from_home(self.community_name)
@@ -407,7 +407,7 @@ class TestActivityMultipleDevicePRTwo(MultipleSharedDeviceTestCase):
self.home_1.just_fyi("Open community to message")
self.home_1.communities_tab.click()
self.community_name = "open community"
self.community_name = "Open community"
self.channel_name = 'general'
self.home_1.create_community(community_type="open")
self.channel_1 = self.home_1.get_to_community_channel_from_home(self.community_name)
@@ -468,7 +468,7 @@ class TestActivityMultipleDevicePRTwo(MultipleSharedDeviceTestCase):
self.home_1.just_fyi("Open community to message")
self.home_1.communities_tab.click()
community_name = 'closed community'
community_name = 'Closed community'
self.channel_name = "dogs"
self.home_1.create_community(community_type="closed")
self.home_1.reopen_app()
@@ -25,7 +25,7 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
self.home = self.sign_in.create_user(username=self.username)
self.home.communities_tab.click_until_presence_of_element(self.home.plus_community_button)
self.community_name = "closed community"
self.community_name = "Closed community"
self.channel_name = "cats"
self.community = self.home.create_community(community_type="closed")
@@ -307,7 +307,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.home_1.just_fyi("Open community to message")
self.home_1.communities_tab.click()
self.community_name = "open community"
self.community_name = "Open community"
self.channel_name = 'general'
self.home_1.create_community(community_type="open")
self.channel_1 = self.home_1.get_to_community_channel_from_home(self.community_name)
@@ -828,7 +828,7 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
self.home_1.just_fyi("Open community to message")
self.home_1.communities_tab.click()
self.community_name = "open community"
self.community_name = "Open community"
self.channel_name = 'general'
self.home_1.create_community(community_type="open")
@@ -1004,7 +1004,7 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
self.home_1.just_fyi("Device 1 creates a closed community")
self.home_1.create_community(community_type="closed")
community_name = "closed community"
community_name = "Closed community"
self.community_1.share_community(community_name, self.username_2)
self.community_1.get_to_community_channel_from_home(community_name, "general")
control_message_general_chat = "this message should be visible to the user before joining"
@@ -1104,7 +1104,7 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
self.home_1.just_fyi("Device 1 creates open community")
self.home_1.create_community(community_type="open")
community_name = "open community"
community_name = "Open community"
self.community_1.share_community(community_name, self.username_2)
self.community_1.get_to_community_channel_from_home(community_name, "general")
control_message_general_chat = "this message should be visible to the user before joining"
@@ -17,7 +17,7 @@ class TestDeepLinksOneDevice(MultipleSharedDeviceTestCase):
self.home = self.sign_in.create_user(username=self.username)
self.home.communities_tab.click_until_presence_of_element(self.home.plus_community_button)
self.community_name = "open community"
self.community_name = "Open community"
self.channel_name = "general"
self.community = self.home.create_community(community_type="open")
self.profile_view = self.home.get_profile_view()