pzp-wiki/guide/concepts/feed.md

3.9 KiB

sidebar_position
30

Feed

:::note Definition A feed is an evolving set of interlinked messages intended for continuous replication in a gossip network. :::

In computer science terms, it's an Directed Acyclic Graph (DAG) with only one source node, where all the "nodes" are messages, and "edges" are references that each message contains of other messages.

graph RL;
  D--"A"-->C--"A"-->B--"A"-->A;
  F-->E-->C;
  G-->D & F;

style A color:red;

The root is...

The tangle is identified by the hash of its root message.

Account

An account is a special type of tangle, where the messages describe which keypairs are part of the same "account".

graph RL;
  D--"A"-->C--"A"-->B--"A"-->A;
  F-->E-->C;
  G-->D & F;

style A color:red;

Msgs in an account tangle are special because they have empty account and accountTips fields.

interface Msg {
  data: AccountData
  metadata: {
    dataHash: ContentHash
    dataSize: number
    account: 'self' // MUST be the string 'self'
    accountTips: null // MUST be null
    tangles: {
      [accountTangleId: string]: {
        depth: number // maximum distance (positive integer) from this msg to the root
        prev: Array<MsgHash> // list of msg hashes of existing msgs, unique set and ordered alphabetically
      }
    }
    domain: string // alphanumeric string, at least 3 chars, max 100 chars
    v: 3
  }
  pubkey: Pubkey
  sig: Signature
}

type AccountData =
  | { action: 'add', add: AccountAdd }
  | { action: 'del', del: AccountDel }

// "add" means this keypair can validly add more keypairs to the account tangle
// "del" means this keypair can validly revoke other keypairs from the account
// "box" means the peer with this keypair should get access to the box keypair
type AccountPower = 'add' | 'del' | 'box'

type AccountAdd = {
  key: Key
  nonce?: string // nonce required only on the account tangle's root
  consent?: string // base58 encoded signature of the string `:account-add:<ID>` where `<ID>` is the account's ID, required only on non-root msgs
  accountPowers?: Array<AccountPower> // list of powers granted to this key, defaults to []
}

type AccountDel = {
  key: Key
}

type Key =
  | {
      purpose: 'sig' // digital signatures
      algorithm: 'ed25519' // libsodium crypto_sign_detached
      bytes: string // base58 encoded string for the public key being added
    }
  | {
      // WIP!!
      purpose: 'box' // asymmetric encryption
      algorithm: 'x25519-xsalsa20-poly1305' // libsodium crypto_box_easy
      bytes: string // base58 encoded string of the public key
    }

Examples of accountData:

  • Registering the first signing pubkey:
    {
      "action": "add",
      "add": {
        "key": {
          "purpose": "sig",
          "algorithm": "ed25519",
          "bytes": "3JrJiHEQzRFMzEqWawfBgq2DSZDyihP1NHXshqcL8pB9"
        },
        "nonce": "6GHR1ZFFSB3C5qAGwmSwVH8f7byNo8Cqwn5PcyG3qDvS"
      }
    }
    
  • Registering a subaccount:
    {
      "action": "add",
      "add": {
        "key": {
          "purpose": "subaccount",
          "algorithm": "tangle",
          "bytes": "6yqq7iwyJEKdofJ3xpRLEq"
        }
      }
    }
    
  • Revoking a signing pubkey:
    {
      "action": "del",
      "del": {
        "key": {
          "purpose": "sig",
          "algorithm": "ed25519",
          "bytes": "3JrJiHEQzRFMzEqWawfBgq2DSZDyihP1NHXshqcL8pB9"
        }
      }
    }
    

Moot feeds

A feed is a special type of tangle, where the root is a predictable (by any peer) message with no content.

graph RL;
  D--"A"-->C--"A"-->B--"A"-->A;
  F-->E-->C;
  G-->D & F;

style A color:red;

Root:

interface Msg {
  data: null // MUST be null
  metadata: {
    dataHash: null // MUST be null
    dataSize: 0 // MUST be 0
    account: string // MUST be an ID
    accountTips: null // MUST be null
    tangles: {} // MUST be empty object
    domain: string
    v: 2
  }
  pubkey: Pubkey
  sig: Signature
}