"use strict";(self.webpackChunkpzp_wiki=self.webpackChunkpzp_wiki||[]).push([[2385],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>h});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var o=n.createContext({}),p=function(e){var t=n.useContext(o),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},u=function(e){var t=p(e.components);return n.createElement(o.Provider,{value:t},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,l=e.originalType,o=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=p(a),d=r,h=c["".concat(o,".").concat(d)]||c[d]||m[d]||l;return a?n.createElement(h,i(i({ref:t},u),{},{components:a})):n.createElement(h,i({ref:t},u))}));function h(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=a.length,i=new Array(l);i[0]=d;var s={};for(var o in t)hasOwnProperty.call(t,o)&&(s[o]=t[o]);s.originalType=e,s[c]="string"==typeof e?e:r,i[1]=s;for(var p=2;p{a.r(t),a.d(t,{assets:()=>o,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>s,toc:()=>p});var n=a(7462),r=(a(7294),a(3905));const l={sidebar_position:1},i="PZP Docs",s={unversionedId:"intro",id:"intro",title:"PZP Docs",description:'What is "PZP":',source:"@site/guide/intro.md",sourceDirName:".",slug:"/intro",permalink:"/guide/intro",draft:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/guide/intro.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Philosophy",permalink:"/guide/category/philosophy"}},o={},p=[{value:"Features",id:"features",level:2},{value:"How PZP is different from SSB (Secure Scuttlebutt)",id:"how-pzp-is-different-from-ssb-secure-scuttlebutt",level:3},{value:"How PZP is different from Nostr",id:"how-pzp-is-different-from-nostr",level:3},{value:"Tangles",id:"tangles",level:2},{value:"Account Tangle",id:"account-tangle",level:3},{value:"Feed Tangle",id:"feed-tangle",level:3},{value:"Thread Tangle",id:"thread-tangle",level:3},{value:"Messages",id:"messages",level:2},{value:"RPC methods",id:"rpc-methods",level:2},{value:"Other",id:"other",level:2}],u={toc:p},c="wrapper";function m(e){let{components:t,...a}=e;return(0,r.kt)(c,(0,n.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"pzp-docs"},"PZP Docs"),(0,r.kt)("p",null,'What is "PZP":'),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"A local-first P2P protocol with 10 years of learnings baked in"),(0,r.kt)("li",{parentName:"ul"},"Message formats + Message validation + RPC methods"),(0,r.kt)("li",{parentName:"ul"},"If scuttlebutt is \ud83d\ude42 then pzp is \ud83d\ude0e ")),(0,r.kt)("p",null,"What it doesn't specify:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Disk storage")),(0,r.kt)("h2",{id:"features"},"Features"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"sig-chains - you know what the messages are"),(0,r.kt)("li",{parentName:"ul"},"first class multi-device support"),(0,r.kt)("li",{parentName:"ul"},"partial replication (using lipmaa links)"),(0,r.kt)("li",{parentName:"ul"},"message deletion (can leave nothing, or only metadata)")),(0,r.kt)("h3",{id:"how-pzp-is-different-from-ssb-secure-scuttlebutt"},"How PZP is different from SSB (Secure Scuttlebutt)"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Storage is designed to not grow indefinitely. By default (of course overridable) an app's storage shouldn't go above 100MB."),(0,r.kt)("li",{parentName:"ul"},"Multi device/app support from the start. Every device/app has its own keypair. They're connected together into one identity using an Account tangle. The Account tangle's root message ID is the account's identifier."),(0,r.kt)("li",{parentName:"ul"},"One account or even keypair can post messages concurrently (forking) without problem. Because there aren't linear feeds, everything is in tangles."),(0,r.kt)("li",{parentName:"ul"},"Deletion is possible. The data contents of a message is separate from the message metadata, and only the metadata + hash of the data is signed."),(0,r.kt)("li",{parentName:"ul"},"When messages are getting signed they get serialized according to ",(0,r.kt)("a",{parentName:"li",href:"https://tools.ietf.org/html/rfc8785"},"RFC 8785"),"."),(0,r.kt)("li",{parentName:"ul"},"Easy to use invites")),(0,r.kt)("h3",{id:"how-pzp-is-different-from-nostr"},"How PZP is different from Nostr"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"keys are not shared across devices"),(0,r.kt)("li",{parentName:"ul"},"sig-chains - you know if you're missing content in PZP"),(0,r.kt)("li",{parentName:"ul"},"trust based - invite only")),(0,r.kt)("h2",{id:"tangles"},"Tangles"),(0,r.kt)("p",null,"Tangles control how messages are organised. They provide a way to group, and causally sort (partially), which is important for replication."),(0,r.kt)("p",null,"Basics of tangles in PZP: it's a directed acyclic graph (DAG) which aims to be as linear as possible"),(0,r.kt)("mermaid",{value:"flowchart RL\n\nE --\x3e D --\x3e C --\x3e A\n D --\x3e B --\x3e A"}),(0,r.kt)("p",null,"There are 3 sorts of tangles:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Account - a tangle which weaves (device) keys and defines capabilities / permissions of these"),(0,r.kt)("li",{parentName:"ul"},"Feed - a tangle where all messages are from valid devices (as defined by an Account), and scoped to a particular domain",(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},'e.g. all post messages from "mix"'),(0,r.kt)("li",{parentName:"ul"},'e.g. all chess messages from "happy0"'))),(0,r.kt)("li",{parentName:"ul"},"Thread - a tangle where multiple Accounts are collaborating on some state",(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},'e.g. all the messages making up a "10th birthday gathering"'),(0,r.kt)("li",{parentName:"ul"},"e.g. all the messages in a discussion"),(0,r.kt)("li",{parentName:"ul"},"e.g. all the messages in a shared shopping list")))),(0,r.kt)("h3",{id:"account-tangle"},"Account Tangle"),(0,r.kt)("p",null,'The account tangle starts with a message which says "This key is allowed to author messages on behalf of this account, and add further keys".'),(0,r.kt)("p",null,"Subsequent messages in this tangle may add / remove capabilities for existing / new keys."),(0,r.kt)("p",null,"Messages in this tangle are verified by checking state they're extending on"),(0,r.kt)("h3",{id:"feed-tangle"},"Feed Tangle"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Domain Tangle, AccountDomain Tangle")),(0,r.kt)("h3",{id:"thread-tangle"},"Thread Tangle"),(0,r.kt)("p",null,"All tangles have"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"a root / root message"),(0,r.kt)("li",{parentName:"ul"},"an ID (the id of the root message of the tangle)"),(0,r.kt)("li",{parentName:"ul"},"have tangle-data for causal ordering")),(0,r.kt)("p",null,"How the tangles differ"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"the Account tangle has strict validation of messages (it is only valid to write to it if you've been given permission to)"),(0,r.kt)("li",{parentName:"ul"},"a Feed root is deterministic! (only inputs are accountId + domain)")),(0,r.kt)("h2",{id:"messages"},"Messages"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/staltz/ppppp-db/blob/master/protospec.md"},"https://github.com/staltz/ppppp-db/blob/master/protospec.md")),(0,r.kt)("h2",{id:"rpc-methods"},"RPC methods"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/staltz/ppppp-sync/blob/master/protospec.md"},"Replication"))),(0,r.kt)("h2",{id:"other"},"Other"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("a",{parentName:"p",href:"https://github.com/staltz/ppppp-invite/blob/master/protospec.md"},"ppppp-invite"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("a",{parentName:"p",href:"https://github.com/staltz/ppppp-set/blob/master/protospec.md"},"ppppp-set"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("a",{parentName:"p",href:"https://github.com/staltz/ppppp-dict/blob/master/protospec.md"},"ppppp-dict")))))}m.isMDXComponent=!0}}]);