Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Socket
Sign inDemoInstall

ssb-crut

Package Overview
Dependencies
Maintainers
4
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ssb-crut

easy CRUT methods for secure scuttlebutt


Version published
Maintainers
4
Created
Source

ssb-crut

Easily mint CRUD (Create, Read, Update, Delete) methods for scuttlebutt records! Note there is no Delete, so instead we have T for Tombstone (CRUT!)

Example usage

const Crut = require('ssb-crut')
const Overwrite = require('@tangle/overwrite')
const SimpleSet = require('@tangle/simple-set')

const spec = {
  type: 'gathering',
  props: {
    title: Overwrite(),
    description: Overwrite(),
    attendees: SimpleSet(),
  },
}

const crut = new Crut(server, spec)

crut.create(
  { 
    title: 'Ahau launch party',
    attendees: { add: ['Mix'] }

    // staticProps
    recps: ['%group'] },             
  },
  (err, gatheringId) => {
    //
  }
)

// later

crut.update(
  gatheringId
  {
    description: "Let's celebrate this new phase!",
    attendees: { add: ['Cherese'] }  // props
  },
  (err, updateId) => {
    //
  }
)

API

new CRUT(server, spec) => crut

Takes an scuttelbutt server instance and a spec and returns an crut instance with methods for mutable records.

A spec is an Object with properties:

  • type String - directly related to the type field that will occur on messages
  • props Strategy
    • defines how the mutable parts of the record will behaved.
    • Create this with @tangle/strategy

Optional properties:

  • tangle String
    • where the tangle info will be stored content.tangles[tangle]
    • defaults to type.split('/')[0]
  • staticProps Object
    • a list of props which are not mutable, and will be baked into root message
    • format is in JSON Schema, for example:
    {
      source: { type: 'string', required: true },
      live: { type: 'boolean' }
    }
    
  • isValidNextStep Function
    • a function run before writing and during reading to confirm the validity of message extending the tangle
    • signature: fn(context, msg) => Boolean where
      • context = { accT, graph }. accT` is the accumulated transform for the position immediately before this message in the tangle.
      • msg the update message being assessed
    • used by:
      • create to check the message about to be published is valid. In this case accT = I, the (empty) identity transform.
      • update to check the message about to be published is valid given the existing tangle state it would extend
      • read to determine which messages are valid to include in reducing
    • NOTE - in the get + update check you don't currently have access to context.graph
  • hooks Object with properties:
    • isRoot Array a collection of validator functions which each root message must pass to proceed
    • isUpdate Array a collection of validator functions which each update message must pass to proceed
  • getTransformation Function
    • a function which is used to map a full message ({ key, value }) to a transformation
    • default: m => m.value.content
    • NOTE: if you're careful you can use this to decorate you transformation values with e.g. author info

crut.create(allProps, cb)

Makes a new record, and calls back with the id of that record.

  • allProps Object
    • none/ some/ all of the properties declared in spec.props
    • none/ some/ all of the properties declared in spec.staticProps

Message content is checked with isRoot before publishing.

crut.read(id, cb)

Takes a record id and calls back with a Record.

A tangle here is a collection of messages linked in a directed acyclic graph. Each of thee messages contains an "operational transform" which is an instuction about how to update the record state.

Transformations are concatenated (added up) while traversing the graph.

For a tangle made up of messages linked like this:

      A     << root
     / \
    B   C   << concurrent updates
        |
        D   << an update which is also a tip

Then the reduced Record would look like:

{
  key: A,          // the key of the tangle root message
  type,
  ...staticProps,  // any staticProp values
  states: [
    {
      key: D,      // key of tangle tip message
      ...props     // reified state of props for this tangle tip
    },
    {
      key: B,      // key of tangle tip message
      ...props     // reified state of props for this tangle tip
    }
  }
}

There will be 1 or more "states" depending on whether the tangle is a in a branched / forked state at the moment.

The state of the props returned are "riefied" (meaning has been made real), because often the transformation format is optimised for mathematical properties, but not very human friendly.

NOTES:

  • states is sorted "most recent" to "least recent" by the tip messages's declared timestamp.

crut.update(id, props, cb)

Updates record id. The props provided are used to generate a transformation which is then checked with isValidUpdate (if provided).

Message contents are also checked against isUpdate before publishing. Calls back with the key of the update message published.

NOTES:

  • by default, updates are accepted from everyone
  • to change this, specifiy behaviour in isValidUpdate e.g.
spec.isValidUpdate = (context, msg) => {
  const { accT, graph } = context

  if (!graph) return true
  // crut.read has graph, but crut.update doesn't yet
  // this means updates from others can be published but will be ignored

  return graph.rootNodes.some(root => {
    return root.value.author === msg.value.author
  })
}

crut.tombstone(id, reason, cb)

:warning: TODO

A convenience helper mainly here to put the T in CRUT. Requires props strategy with{ tombstone: require('tangle/overwrite)() }

Calls back with the key of the update message which tombstoned.


Notes

  • crut.update does not currently publish merges

    • currently extends the tip with most recent activity
    • want to change this in the future but @tangle/reduce will needs more work
  • need to add support for ssb-recps-guard

    • create
    • update
    • tombstone
    • add docs - basically add allowProps: true to props
  • want to remove isRoot + isUpdate

    • auto-generate them from type, tangle, staticProps, props
    • would need strategies to provide schema
    • could still optionally provide these methods
  • need restrictions

    • tangle !=== 'group'
    • props excludes: [type, recps, tangle, ...staticProps]
    • staticProps excludes: [tombstone, tangle, ...props]
    • where should type + recps be ???
  • isValidUpdate currently only receives ({ context }) (no graph)

    • adding the graph is possible but awkward, I think we should only add this if absolutely needed
    • if @tangle/reduce is modified to be able to "update" as new messages come in, that could be useful for this case too (as that will likely have a copy of the graph

Keywords

FAQs

Package last updated on 14 Jan 2021

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc