NEAR-DevHub / neardevhub-contract

DevHub Portal Product Contract (Hosted on NEAR Blockchain) – Includes other instances (e.g. Infrastructure, Events)
https://neardevhub.org
19 stars 15 forks source link

added discussions accounts factory to community contract #88

Closed Tguntenaar closed 9 months ago

Tguntenaar commented 9 months ago

This issue is supporting PR #645

@frolvlad @ailisp I would like to get some feedback on my approach.

I assumed that in order to create discussions.${handle}.community.devhub.near the ${handle}.community.devhub.near account needs to be an factory in itself.

I added this image help describe what I did with some common terminology.

Screenshot 2024-01-23 at 17 31 22

I added a set_discussions_community_socialdb function so the user can post on socialdb from the devhub.near contract. This uses get_devhub_discussions_account which retrieves discussions.<handle>.community.devhub.near.

To support that I added a create_discussions_account function to the community contract. So the community contract is in essence a discussions factory. I copied most of what was the community contract to the discussions contract with some minor tweaks since it is a level down in subaccounts.

In file community/src/lib.rs line 9 and 70 a PUBkey from devhub.near is used to give control to make posts on socialDB. Should this be devhub.near?

ailisp commented 9 months ago

Your approach is working, however it requires deploy a discussion contract per community. Note that it's not the public key that grant permission to write given account's social db, but it's the socialdb.grant_write_permission call. I suggest a simpler way: Currently xxx.community.devhub.near allow devhub.near to set it's social db. So we can add a method in devhub.near contract to set a repost a post that originally post from user, but set it under xxx.community.devhub.near namespace (aka, repost a user's post to the community's account). The payload to set look like:

{
  "xxx.community.devhub.near": {
    "index": {
      "repost": "[{\"key\":\"main\",\"value\":{\"type\":\"repost\",\"item\":{\"type\":\"social\",\"path\":\"nearukraineguild.near/post/main\",\"blockHeight\":111142780}}},{\"key\":{\"type\":\"social\",\"path\":\"nearukraineguild.near/post/main\",\"blockHeight\":111142780},\"value\":{\"type\":\"repost\"}}]",
      "notify": "{\"key\":\"nearukraineguild.near\",\"value\":{\"type\":\"repost\",\"item\":{\"type\":\"social\",\"path\":\"nearukraineguild.near/post/main\",\"blockHeight\":111142780}}}"
    }
  }
}

Assume this method in devhub.near is called repost_user_post_to_community.

Now from frontend, when user create a discussion, we want to post as a near social post (easy) and also repost by call repost_user_post_to_community, th

But you can see there is a problem: repost requires the blockHeight of the original post, it's not possible to get it in a batch transaction from frontend. So we need to convert devhub.repost_user_post_to_community to a cross contract call: it first call socialdb.set to create user post, then socialdb.get to obtain the post's blockHeight, then call socialdb.set to set repost under xxx.community.devhub.near namespace

Tguntenaar commented 9 months ago

@frol @ailisp I removed the discussions factory as discussed with @ailisp. We will look post discussions to xxx.community.devhub.near. We wil distinguish the two by their type. Announcements will be posts on the xxx.community.devhub.near account, while discussions will fall under reposts of what a user posted on their own account first.

frol commented 9 months ago

@ailisp @Tguntenaar The reason I wanted to have a separate account (discussions. sub-account) is to allow users to follow only announcements if necessary, and also the global "DevHub Communities Announcements" would be just a feed of community.devhub.near account which would just follow all the announcement accounts (xxx.community.devhub.near) - we would just need to add one more call to subscribe community.devhub.near to follow all the created communities (but not discussions).

@Tguntenaar I am sorry, but I would like to ask you to get the discussions factory back.

Once again, I want a clear separation between announcements and discussions. This allows us to use the standard SocialDB Index API (just like Social feed does), and be completely compatible with the rest of NEAR Social ecosystem.

Tguntenaar commented 9 months ago

@frol Alright no problem, I will revert those lasts commit back than. Also in the front PR

frol commented 9 months ago

@Tguntenaar Let's also extends the community tests to check that discussions are also properly configured

Tguntenaar commented 9 months ago

@frol @ailisp @petersalomonsen Hey guys! The discussions tests fails with the following error: [account discussions.gotham.community.devhub.near does not exist while viewing]

So the create_community function does not properly deploy the account : discussions.{handle}.community.devhub.near. How would you guys debug this properly?

I think it has to do with the async nature of the cross contract call which isn't returned by create_community since it is wrapped in a .then.

So a solution would be to make create_community async or call the create_discussion_account from another place where it makes more sense.

petersalomonsen commented 9 months ago

@frol @ailisp @petersalomonsen Hey guys! The discussions tests fails with the following error: [account discussions.gotham.community.devhub.near does not exist while viewing]

So the create_community function does not properly deploy the account : discussions.{handle}.community.devhub.near. How would you guys debug this properly?

I think it has to do with the async nature of the cross contract call which isn't returned by create_community since it is wrapped in a .then.

So a solution would be to make create_community async or call the create_discussion_account from another place where it makes more sense.

I think you need to test this in the integration test and not in the unit test. I see you are trying to call create_discussion_account in the tests of src/lib.rs, but since this has all the cross contract calling and all that, you should rather test this in the end-to-end tests that you have in tests/communitites.rs.