Is it possible to programatically update a model associated with a user?

One of the main features of MetaGame is a SourceCred leaderboard that ranks players based on their receipt of a “cred” token from SourceCred.

In our transition to ComposeDB, we are going to try to remove a caching layer that we are currently using which stores all the player profiles in a Hasura instance. In order to query ComposeDB and get back an appropriate list to generate the leaderboard, ComposeDB needs to know what player’s cred scores are.

I understand that given a DID, it is possible to retrieve streams that are controlled by that DID. To maintain the cred score, however, there would be some external process updating the scores once a day or so. That process would be operating with a DID:KEY, more than likely.

Can I associate the stream for the app with the users’ streams. I’d like to write something like:

query Leaderboard {
  player(order_by: {cred: {score: asc}}, where: {cred: {organization: {_eq: "MetaGame"}}}) {
    name
    username
    backgroundImageURL
    cred: {
      score
    }
  }
}

Where the user added the name / username / etc., and an app set cred.score.

Or would I do something like have the user generate a CACAO permission giving the app the right to write their cred value? This requires a user interaction (plus regular refreshes) to add the player to the leaderboard, so it’s not ideal.

Hey, @dysbulic , thanks for reaching out and sharing your use case!

I think the main question to answer is who do you want to own the cred scores.

We encourage developers to have their users own their data and delegate write permissions to dApps using CACAO and DID Sessions. Devs can configure DID Sessions’ expiry time however they want, as long as their users are ok with that.

Assuming that your users own both their profile and their cred scores, you can do the following.

First of all, unless there’s already a profile model fitting your needs, you could create a composite with a Profile model like:

type Profile @createModel(accountRelation: SINGLE, description: "Profile") {
  displayName: String! @string(...)
  username: String! @string(...)
  ...
}

Then you could create a composite with a SourceCredScore model like:

type Profile @loadModel(id: "<existing Profile model stream ID>") {
  id: ID!
}

type SourceCredScore @createModel(accountRelation: SINGLE, description: "SourceCred Score") {
  profile: StreamID! @documentReference(model: "Profile")
  cred: Int! @int(...)
}

Then you can query like this:

query {
  viewer {
    profile {
      displayName
      username
    }
    sourceCredScore {
      cred
    }
  }
}

If you really don’t want your users to own their cred scores, you could define the SourceCredScore model with accountRelation: LIST and have your app’s did:key own instances of that model.

If you do that, however, then with the current version of ComposeDB would no easy way to retrieve the scores in the same graphQL query that you’d use to retrieve a particular profile. There’d also be no way to filter SourceCredScore instances by profile ids. You’d have to query your ceramic node’s index database directly to achieve that.

1 Like