Files
rfc.vac.dev/assets/js/1a6e896f.1c8ee889.js
2025-08-01 18:13:23 +00:00

1 line
11 KiB
JavaScript

"use strict";(self.webpackChunklogos_docs_template=self.webpackChunklogos_docs_template||[]).push([[846],{45289:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>l,toc:()=>u});var n=a(87462),r=(a(67294),a(3905));const i={title:"STATUS-URL-DATA",name:"Status URL Data",status:"raw",category:"Standards Track",editor:"Felicio Mununga &lt;felicio@status.im&gt;",contributors:["Aaryamann Challani &lt;aaryamann@status.im&gt;"]},o=void 0,l={unversionedId:"raw/url-data",id:"raw/url-data",title:"STATUS-URL-DATA",description:"- Status: raw",source:"@site/status/raw/url-data.md",sourceDirName:"raw",slug:"/raw/url-data",permalink:"/status/raw/url-data",draft:!1,tags:[],version:"current",frontMatter:{title:"STATUS-URL-DATA",name:"Status URL Data",status:"raw",category:"Standards Track",editor:"Felicio Mununga &lt;felicio@status.im&gt;",contributors:["Aaryamann Challani &lt;aaryamann@status.im&gt;"]},sidebar:"defaultSidebar",previous:{title:"STATUS-MVDS-USAGE",permalink:"/status/raw/status-mvds"},next:{title:"STATUS-URL-SCHEME",permalink:"/status/raw/url-scheme"}},s={},u=[{value:"Abstract",id:"abstract",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Wire Format",id:"wire-format",level:2},{value:"Implementation",id:"implementation",level:2},{value:"Compression",id:"compression",level:3},{value:"Serialization",id:"serialization",level:3},{value:"Implementation Pseudocode",id:"implementation-pseudocode",level:3},{value:"Decoding",id:"decoding",level:4},{value:"Example",id:"example",level:3},{value:"Discussions",id:"discussions",level:2},{value:"Proof of concept",id:"proof-of-concept",level:2},{value:"Copyright",id:"copyright",level:2},{value:"References",id:"references",level:2}],c={toc:u};function p(e){let{components:t,...a}=e;return(0,r.kt)("wrapper",(0,n.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Status: raw"),(0,r.kt)("li",{parentName:"ul"},"Category: Standards Track"),(0,r.kt)("li",{parentName:"ul"},"Editor: Felicio Mununga ","<",(0,r.kt)("a",{parentName:"li",href:"mailto:felicio@status.im"},"felicio@status.im"),">"),(0,r.kt)("li",{parentName:"ul"},"Contributors:",(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Aaryamann Challani ","<",(0,r.kt)("a",{parentName:"li",href:"mailto:aaryamann@status.im"},"aaryamann@status.im"),">")))),(0,r.kt)("h2",{id:"abstract"},"Abstract"),(0,r.kt)("p",null,"This document specifies serialization, compression, and\nencoding techniques used to transmit data within URLs in the context of Status protocols."),(0,r.kt)("h2",{id:"motivation"},"Motivation"),(0,r.kt)("p",null,"When sharing URLs,\nlink previews often expose metadata to the websites behind those links.\nTo reduce reliance on external servers for providing appropriate link previews,\nthis specification proposes a standard method for encoding data within URLs."),(0,r.kt)("h2",{id:"terminology"},"Terminology"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Community: Refer to ",(0,r.kt)("a",{parentName:"li",href:"../56/communities"},"STATUS-COMMUNITIES")),(0,r.kt)("li",{parentName:"ul"},"Channel: Refer to terminology in ",(0,r.kt)("a",{parentName:"li",href:"../56/communities"},"STATUS-COMMUNITIES")),(0,r.kt)("li",{parentName:"ul"},"User: Refer to terminology in ",(0,r.kt)("a",{parentName:"li",href:"../56/communities"},"STATUS-COMMUNITIES")),(0,r.kt)("li",{parentName:"ul"},"Shard Refer to terminology in ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/waku-org/specs/blob/master/standards/core/relay-sharding.md"},"WAKU2-RELAY-SHARDING"))),(0,r.kt)("h2",{id:"wire-format"},"Wire Format"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-protobuf"},'syntax = "proto3";\n\nmessage Community {\n // Display name of the community\n string display_name = 1;\n // Description of the community\n string description = 2;\n // Number of members in the community\n uint32 members_count = 3;\n // Color of the community title\n string color = 4;\n // List of tag indices\n repeated uint32 tag_indices = 5;\n}\n\nmessage Channel {\n // Display name of the channel\n string display_name = 1;\n // Description of the channel\n string description = 2;\n // Emoji of the channel\n string emoji = 3;\n // Color of the channel title\n string color = 4;\n // Community the channel belongs to\n Community community = 5;\n // UUID of the channel\n string uuid = 6;\n}\n\nmessage User {\n // Display name of the user\n string display_name = 1;\n // Description of the user\n string description = 2;\n // Color of the user title\n string color = 3;\n}\n\nmessage URLData {\n // Community, Channel, or User\n bytes content = 1;\n uint32 shard_cluster = 2;\n uint32 shard_index = 3;\n}\n')),(0,r.kt)("h2",{id:"implementation"},"Implementation"),(0,r.kt)("p",null,"The above wire format describes the data encoded in the URL.\nThe data MUST be serialized, compressed, and encoded using the following standards:"),(0,r.kt)("p",null,"Encoding"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://datatracker.ietf.org/doc/html/rfc4648"},"Base64url"))),(0,r.kt)("h3",{id:"compression"},"Compression"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://datatracker.ietf.org/doc/html/rfc7932"},"Brotli"))),(0,r.kt)("h3",{id:"serialization"},"Serialization"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://protobuf.dev/reference/protobuf/proto3-spec/"},"Protocol buffers version 3"))),(0,r.kt)("h3",{id:"implementation-pseudocode"},"Implementation Pseudocode"),(0,r.kt)("p",null,"Encoding"),(0,r.kt)("p",null,"Encoding the URL MUST be done in the following order:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-protobuf"},"raw_data = {User | Channel | Community}\nserialized_data = protobuf_serialize(raw_data)\ncompressed_data = brotli_compress(serialized_data)\nencoded_url_data = base64url_encode(compressed_data)\n")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"encoded_url_data")," is then used to generate a signature using the private key."),(0,r.kt)("h4",{id:"decoding"},"Decoding"),(0,r.kt)("p",null,"Decoding the URL MUST be done in the following order:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-protobuf"},"url_data = base64url_decode(encoded_url_data)\ndecompressed_data = brotli_decompress(url_data)\ndeserialized_data = protobuf_deserialize(decompressed_data)\nraw_data = deserialized_data.content\n")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"raw_data")," is then used to construct the appropriate data structure\n(User, Channel, or Community)."),(0,r.kt)("h3",{id:"example"},"Example"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"See ","<",(0,r.kt)("a",{parentName:"li",href:"https://github.com/status-im/status-web/pull/345/files"},"https://github.com/status-im/status-web/pull/345/files"),">")),(0,r.kt)("h2",{id:"discussions"},"Discussions"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"See ","<",(0,r.kt)("a",{parentName:"li",href:"https://github.com/status-im/status-web/issues/327"},"https://github.com/status-im/status-web/issues/327"),">")),(0,r.kt)("h2",{id:"proof-of-concept"},"Proof of concept"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"See ","<",(0,r.kt)("a",{parentName:"li",href:"https://github.com/felicio/status-web/blob/825262c4f07a68501478116c7382862607a5544e/packages/status-js/src/utils/encode-url-data.compare.test.ts#L4"},"https://github.com/felicio/status-web/blob/825262c4f07a68501478116c7382862607a5544e/packages/status-js/src/utils/encode-url-data.compare.test.ts#L4"),">")),(0,r.kt)("h2",{id:"copyright"},"Copyright"),(0,r.kt)("p",null,"Copyright and related rights waived via ",(0,r.kt)("a",{parentName:"p",href:"https://creativecommons.org/publicdomain/zero/1.0/"},"CC0"),"."),(0,r.kt)("h2",{id:"references"},"References"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"https://docs.google.com/spreadsheets/d/1JD4kp0aUm90piUZ7FgM_c2NGe2PdN8BFB11wmt5UZIY/edit?usp=sharing"},"Proposal Google Sheet")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"https://datatracker.ietf.org/doc/html/rfc4648"},"Base64url")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"https://datatracker.ietf.org/doc/html/rfc7932"},"Brotli")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"https://protobuf.dev/reference/protobuf/proto3-spec/"},"Protocol buffers version 3")),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("a",{parentName:"li",href:"./url-scheme"},"STATUS-URL-SCHEME"))))}p.isMDXComponent=!0},3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>d});var n=a(67294);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 i(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 o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var s=n.createContext({}),u=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),m=u(a),d=r,f=m["".concat(s,".").concat(d)]||m[d]||p[d]||i;return a?n.createElement(f,o(o({ref:t},c),{},{components:a})):n.createElement(f,o({ref:t},c))}));function d(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:r,o[1]=l;for(var u=2;u<i;u++)o[u]=a[u];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}m.displayName="MDXCreateElement"}}]);