8000 GitHub - decide-ai/sdk: MODCLUB SDK for integrating your canister with MODCLUB to enable decentralized content moderation and proof of humanity
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
/ sdk Public

MODCLUB SDK for integrating your canister with MODCLUB to enable decentralized content moderation and proof of humanity

License

Notifications You must be signed in to change notification settings

decide-ai/sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MODCLUB

MODCLUB is a moderation platform for online apps deployed on the IC. Moderation as a service (MaaS) is the concept of outsourcing controversial decisions or risky content in order to protect users and maintain trust within communities.

MODCLUB Integration Diagram

Screenshot 2023-10-23 at 6 04 14 PM

Usage

To integrate with MODCLUB, you need to perform the below steps:

  1. Provide your canister ID to MODCLUB team first so that it can be allowed listed.

  2. Import Modclub sdk in to your canister either using vessel(recommended) or copy pasting the src/modclub.mo file. The example provided uses vessel to fetch Modclub SDK for integration. This is how you set vessel up:

    • follow the "getting started" instructions here to install and setup vessel on your machine

    • modify your package-set.dhall and include the modsdk in your additions. make sure you use the latest version from the releases on github:

      let upstream = https://github.com/dfinity/vessel-package-set/releases/download/mo-0.6.21-20220215/package-set.dhall sha256:b46f30e811fe5085741be01e126629c2a55d4c3d6ebf49408fb3b4a98e37589b
      let Package =
          { name : Text, version : Text, repo : Text, dependencies : List Text }
      let additions = [
          { name = "modsdk"
          , repo = "https://github.com/modclub-app/sdk"
          , version = "0.1.1"
          , dependencies = ["base"] : List Text
          }
      ] : List Package
      in upstream # additions
      
    • make sure you also add the library as a dependency to your vessel.dhall file like this:

      {
      dependencies = [ "base", "modsdk" ],
      compiler = Some "0.6.11"
      }
      
  3. Register with Modclub. You can use the following command to get the companyLogoNat8Format from your Logo:

    for byte in ${(j:,:)$(od -An -v -tuC <path to your logo>)[@]}; echo "$byte"

    Substitute <path to your logo> with the correct path to your Logo. Make sure you set the correct mime type for the logo as well, e.g. imageType = "image/svg+xml" for a SVG logo.

    // If you are using Vessel
    import Modclub "mo:modsdk/modclub";
    
    // If you are using SDK after copy pasting the modclub.mo file.
    import Modclub "./modclub";
    
    actor {
        private env : Text = "prod"; // "qa" and "dev" are also available options, for testing purposes
    
        public func setup() {
            let companyLogoInNat8Format : [Nat8] = [255, 216, 255, 224, 0];
            let companyLogo : Modclub.Image = {
                data = companyLogoInNat8Format;
                imageType = "image/jpeg";
            };
            // Register with Modclub
            let _ = await Modclub.initProvider(env, "TestProviderApp", "AppDescription", ?companyLogo);
        }
    }

    ⚠️ You only need to register once: After the registration is done you can remove the setup method from your canister!

Managing Content Rules

Once registered, you can set the rules that moderators should use to evaluate if the submitted content violates those them or not.

addRules - Add content rules Params:

  • rules - [Text] - An array of Texts that describe your content rules
  • providerId - ?Principal - Optional Canister/Provider Id for which rules need to be registered

removeRules - Remove existing rules Params:

  • ruleIds - [Text] - An array of Rule Ids that you would like to remove
  • providerId - ?Principal - Optional Canister/Provider Id for which rules need to be removed

getProviderRules - Returns the list of rules caller has set up

Registering Callback

In order for your application to be aware of when some content has been either approved or rejected, you can register a callback with MODCLUB.

subscribe - Suscribe your call back with MODCLUB Params:

  • callback - SubscribeMessage - The callback function you want to subscribe

The callback should have the following type

  public type SubscribeMessage = { callback: shared ContentResult -> (); };

Example of registering your callback:

  public func subscribe() : async() {
    await Modclub.getModclubActor(env).subscribe({callback = voteResult;});

  };

  public func voteResult(result: ContentResult) {
      Debug.print(debug_show(result));
  };

Submitting Content

Once your app is registered you can submit content to MODCLUB to be reviewed, but first of all you have to ensure that your app-canister owns some MOD tokens and use following method to topUp your ProviderAccount on modclubPlatform:

await Modclub.topUpReserveBalance(env, amount);

This is required because each task you submit has a cost and without any MOD in your account any task submission will fail.

To submit content please use the following methods:

submitText Params:

  • sourceId - Text - The unique ID for this content on your platform.
  • text - Text - The text content to be reviewed
  • title (optional) - Text - An optional title for this content
  • level (optional) - Variant(#simple, #normal, #hard, #xhard) - An optional complexity level for this content (defaults to simple). This determines how many moderators review the task, higher complexity results in more moderators and higher cost.
  • category (optional) - Text - An optional category string that will help modclub moderators filter specific tasks (i.e "Adult", "Gaming", "#MainChannel" )
await Modclub.getModclubActor("staging").submitText("my_content_id", "Text content to be reviewed", ?"Title of content");

submitHtmlContent Params:

  • sourceId - Text - The unique ID for this content on your platform.
  • htmlContent - Text - The html content to be reviewed
  • title (optional) - Text - An optional title for this content
  • level (optional) - Variant(#simple, #normal, #hard, #xhard) - An optional complexity level for this content
  • category (optional) - Text - An optional category string that will help modclub moderators filter specific tasks (i.e "Adult", "Gaming", "#MainChannel" )
await Modclub.getModclubActor("staging").submitHtmlContent("my_content_id_123", "<p>Text content to be reviewed</p><img src='/image.png'/>", ?"Title of content");

submitImage Params:

  • sourceId - Text - The unique ID for this content on your platform.
  • image - [Nat8] - A Nat8 array containing the image data
  • imageType - Text - The image mime type i.e image/jpeg, image/png etc..
  • title (optional) - Text - An optional title for this content
  • level (optional) - Variant(#simple, #normal, #hard, #xhard) - An optional complexity level for this content
  • category (optional) - Text - An optional category string that will help modclub moderators filter specific tasks (i.e "Adult", "Gaming", "#MainChannel" )
await Modclub.getModclubActor("staging").submitImage("my_content_id", imageData, "image/png", ?"Title of Image Content");

Adding an Admin

You can add admins to manage your application via our Admin dashboard. This is more convenient if you have other team members that are setting your app's content rules or the moderator settings.

addProviderAdmin Params:

  • userName - Text - The username for the admin
  • userPrincipal - Principal - The principal ID for the admin
  • providerId - ?Principal - The principal ID of your app. (Optional if your app is making this call directly)
  await Modclub.getModclubActor("staging").addProviderAdmin(Principal.fromText("YOUR_STOIC_PRINCIPAL_ID"), "moderator", null);

Proof of Humanity

MODCLUB's POH works as follows, there are different POH challenges that dApps can choose from. For instance an NFT platform might use an audio challenge ( you recite a unique phrase ). They may also use a drawing challenge ( draw a unique set of shapes on a piece of paper ) that would be a video challenge but won't require you to show your face or anything personally identifiable. You can stack on a series of challenges if you would like which further adds to proof that the user is human but that again that is up to the dApp.

POH Integration Diagram

image

Above is an example of integration with Modclub. You can see an example of this achieved in the code here: https://github.com/flowerpowerdao/poh

Current POH Challenges

  • challenge-profile-pic - This challenge requires the user to submit a picture of the face using their camera or by uploading one
  • challenge-user-video - This challenge requires the user to record using their camera a set of 6 random words.
  • chalenge-user-audio - This challenge requires the user to record using their microphone a set of 6 random words.
  • challenge-unique-poh - Similar to the video challenge this requires the user to say 6 random words but this will fail if the users face has been registered before

To get started with Proof of Humanity you must first register your callback method to retrieve the result.

MODCLUB's proof of humanity works To setup proof of humanity you will need to first register

subscribePohCallback This is the callback that MODCLUB will call after a user has completed their POH. Your application should handle the result of this method and perform

 subscribePohCallback: (SubscribePohMessage) -> async ();

verifyHumanity This method you call in order to check if a user has verified their humanity. If they haven't you will receive a token that will be used to redirect the user back to modclub to perform POH.

Parms:

  • uniqueUserId - Text - This is a unique user id that your application is aware of. This could be the principal of the user from your app or a unique string. When a user completes their POH, MODCLUB will call you callback with the users POH result along with this unique identifier.
verifyHumanity: (Text) -> async PohVerificationResponsePlus;

Using POH

public shared({caller}) func exampleToInitiatePOH(): async Text {
        // userId to check if they are a human or not
        let userId = "2vxsx-fae";
        // call to check humanity
        let response =  await Modclub.getModclubActor(environment).verifyHumanity(userId);

        // The user is verified and this is the first time they have associated their account on your application to their modclub POH.
        if(response.status == #verified and response.isFirstAssociation) {
           // In most cases you will only want to accept a POH response that has isFirstAssociation = true so that a user can't reuse their POH
           // with multiple accounts on your platform. For example an NFT allowlist will want the first association of an account to be accepted.
            return "User is verified and first association from your app to modclub";
        };

       // The user has been verified but is reusing their POH
       if(response.status == #verified and not response.isFirstAssociation) {
            return "User is verified but is reusing their modclub POH for another account on your platofrm";
        };

        if((response.status == #startPoh or response.status == #notSubmitted) and response.isFirstAssociation) {
            return "User hasn't done POH or hasn't submitted it. Use this token to start POH: " # Option.get(response.token, "");
        };
        if(response.status == #verified) {
            return "User is verified";
        };

        // The POH has expired in accordance with your configuration. For instance you may only accept POH that was submitted in the last 6 months
        // If the user submitted their POH 7 months ago, then you would receive a status of #expired
        if(response.status == #expired) {
            return "User's POH is expired";
        };
        return "User's POH is pending for review";
    };

About

MODCLUB SDK for integrating your canister with MODCLUB to enable decentralized content moderation and proof of humanity

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  
0