Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added discussions accounts factory to community contract #88

Merged
merged 33 commits into from
Feb 8, 2024

Conversation

Tguntenaar
Copy link
Collaborator

@Tguntenaar Tguntenaar commented Jan 23, 2024

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?

Copy link
Collaborator

@frol frol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first glance, it looks good to me, but it is pretty late in the night, so I will let @ailisp to review it in more details and approve it

@ailisp
Copy link
Collaborator

ailisp commented Jan 24, 2024

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
Copy link
Collaborator Author

@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.

@Tguntenaar Tguntenaar marked this pull request as ready for review January 26, 2024 20:39
@frol
Copy link
Collaborator

frol commented Jan 26, 2024

@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
Copy link
Collaborator Author

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

@frol
Copy link
Collaborator

frol commented Jan 28, 2024

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

@Tguntenaar
Copy link
Collaborator Author

Tguntenaar commented Feb 1, 2024

@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
Copy link
Collaborator

petersalomonsen commented Feb 1, 2024

@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.

src/lib.rs Outdated
Comment on lines 376 to 381
promise.then(
ext_devhub_community::ext(get_devhub_discussions_factory(&new_community.handle))
.with_unused_gas_weight(2)
.with_attached_deposit(CREATE_DISCUSSION_BALANCE)
.create_discussions_account(),
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest the community contract to create the discussion subaccount on new instead of "micro-managing" the community implementation from the main contract.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Tguntenaar Just to clarify. I suggest to make the following separation of concerns:

  1. root contract only calls community factory
  2. community factory only initializes the "announcements" contract
  3. "announcements" contract initializes the "discussions" contract

Pro tip: Since you cannot return a Promise from #[init] method in near-sdk-rs, you can use the low-level API Promise::as_result() while still returning Contract {} from the init function itself. (Update all init functions where it is necessary, to make Promises attached to the result status of the initialization)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to call create_discussions_account from the init function of the "announcements" contract (3).
How can one attach a deposit? I thought an init function isn't payable.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it have to be a method decorated with #[init] to do the initialization? Can't it just be a regular method that you call with a #[payable] decorator?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That works indeed! I'm not sure about the impact though. I guess it won't panic if the state is already initialized.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frol frol marked this pull request as draft February 6, 2024 10:27
@Tguntenaar Tguntenaar force-pushed the feature/584-discussions branch from 5d46a0c to de38459 Compare February 7, 2024 00:46
@Tguntenaar Tguntenaar marked this pull request as ready for review February 7, 2024 14:31
@Tguntenaar Tguntenaar marked this pull request as draft February 7, 2024 16:25
@Tguntenaar Tguntenaar marked this pull request as ready for review February 7, 2024 21:11
Copy link
Collaborator

@ailisp ailisp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@ailisp ailisp merged commit e8e8afe into NEAR-DevHub:main Feb 8, 2024
1 check passed
@frol frol mentioned this pull request Feb 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants