Files
rfc.vac.dev/assets/js/4419c5d1.46b4881d.js
2025-08-01 18:13:23 +00:00

1 line
15 KiB
JavaScript

"use strict";(self.webpackChunklogos_docs_template=self.webpackChunklogos_docs_template||[]).push([[4377],{73002:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>d,frontMatter:()=>n,metadata:()=>o,toc:()=>l});var r=a(87462),i=(a(67294),a(3905));const n={title:"IPFS-gateway-for-Sticker-Pack",name:"IPFS gateway for Sticker Pack",status:"deprecated",description:"This specification describes how Status uses the IPFS gateway to store stickers.",editor:"Filip Dimitrijevic &lt;filip@status.im&gt;",contributors:["Gheorghe Pinzaru &lt;gheorghe@status.im&gt;"]},s=void 0,o={unversionedId:"deprecated/IPFS-gateway-for-sticker-Pack",id:"deprecated/IPFS-gateway-for-sticker-Pack",title:"IPFS-gateway-for-Sticker-Pack",description:"This specification describes how Status uses the IPFS gateway to store stickers.",source:"@site/status/deprecated/IPFS-gateway-for-sticker-Pack.md",sourceDirName:"deprecated",slug:"/deprecated/IPFS-gateway-for-sticker-Pack",permalink:"/status/deprecated/IPFS-gateway-for-sticker-Pack",draft:!1,tags:[],version:"current",frontMatter:{title:"IPFS-gateway-for-Sticker-Pack",name:"IPFS gateway for Sticker Pack",status:"deprecated",description:"This specification describes how Status uses the IPFS gateway to store stickers.",editor:"Filip Dimitrijevic &lt;filip@status.im&gt;",contributors:["Gheorghe Pinzaru &lt;gheorghe@status.im&gt;"]},sidebar:"defaultSidebar",previous:{title:"3RD-PARTY",permalink:"/status/deprecated/3rd-party"},next:{title:"ACCOUNT",permalink:"/status/deprecated/account"}},c={},l=[{value:"Abstract",id:"abstract",level:2},{value:"Definition",id:"definition",level:2},{value:"Specification",id:"specification",level:2},{value:"Image format",id:"image-format",level:3},{value:"Distribution",id:"distribution",level:3},{value:"IPFS gateway",id:"ipfs-gateway",level:3},{value:"Security",id:"security",level:3},{value:"Status sticker usage",id:"status-sticker-usage",level:3},{value:"Submit a sticker",id:"submit-a-sticker",level:4},{value:"Install a sticker pack",id:"install-a-sticker-pack",level:4},{value:"1. Get total number of sticker packs",id:"1-get-total-number-of-sticker-packs",level:4},{value:"2. Get sticker pack by id",id:"2-get-sticker-pack-by-id",level:4},{value:"3. Get owned sticker packs",id:"3-get-owned-sticker-packs",level:5},{value:"4. Buy a sticker pack",id:"4-buy-a-sticker-pack",level:5},{value:"Copyright",id:"copyright",level:2},{value:"References",id:"references",level:2}],p={toc:l};function d(e){let{components:t,...a}=e;return(0,i.kt)("wrapper",(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Status: deprecated"),(0,i.kt)("li",{parentName:"ul"},"Editor: Filip Dimitrijevic ","<",(0,i.kt)("a",{parentName:"li",href:"mailto:filip@status.im"},"filip@status.im"),">"),(0,i.kt)("li",{parentName:"ul"},"Contributors:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Gheorghe Pinzaru ","<",(0,i.kt)("a",{parentName:"li",href:"mailto:gheorghe@status.im"},"gheorghe@status.im"),">")))),(0,i.kt)("h2",{id:"abstract"},"Abstract"),(0,i.kt)("p",null,"This specification describes how Status uses the IPFS gateway",(0,i.kt)("br",{parentName:"p"}),"\n","to store stickers.",(0,i.kt)("br",{parentName:"p"}),"\n","The specification explores image format,",(0,i.kt)("br",{parentName:"p"}),"\n","how a user uploads stickers,",(0,i.kt)("br",{parentName:"p"}),"\n","and how an end user can see them inside the Status app."),(0,i.kt)("h2",{id:"definition"},"Definition"),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Term"),(0,i.kt)("th",{parentName:"tr",align:null},"Description"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Stickers")),(0,i.kt)("td",{parentName:"tr",align:null},"A set of images which can be used to express emotions")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Sticker Pack")),(0,i.kt)("td",{parentName:"tr",align:null},"ERC721 token which includes the set of stickers")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"IPFS")),(0,i.kt)("td",{parentName:"tr",align:null},"P2P network used to store and share data, in this case, the images for the stickerpack")))),(0,i.kt)("h2",{id:"specification"},"Specification"),(0,i.kt)("h3",{id:"image-format"},"Image format"),(0,i.kt)("p",null,"Accepted image file types are ",(0,i.kt)("inlineCode",{parentName:"p"},"PNG"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"JPG/JPEG")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"GIF"),",\nwith a maximum allowed size of 300kb.\nThe minimum sticker image resolution is 512x512,\nand its background SHOULD be transparent."),(0,i.kt)("h3",{id:"distribution"},"Distribution"),(0,i.kt)("p",null,"The node implements sticker packs as ",(0,i.kt)("a",{parentName:"p",href:"https://eips.ethereum.org/EIPS/eip-721"},"ERC721 token"),"\nand contain a set of stickers.\nThe node stores these stickers inside the sticker pack as a set of hyperlinks pointing to IPFS storage.\nThese hyperlinks are publicly available and can be accessed by any user inside the status chat.\nStickers can be sent in chat only by accounts that own the sticker pack."),(0,i.kt)("h3",{id:"ipfs-gateway"},"IPFS gateway"),(0,i.kt)("p",null,"At the moment of writing, the current main Status app uses the ",(0,i.kt)("a",{parentName:"p",href:"https://infura.io/"},"Infura")," gateway.\nHowever, clients could choose a different gateway or to run own IPFS node.\nInfura gateway is an HTTPS gateway,\nwhich based on an HTTP GET request with the multihash block will return the stored content at that block address."),(0,i.kt)("p",null,"The node requires the use of a gateway to enable easy access to the resources over HTTP.\nThe node stores each image of a sticker inside IPFS using a unique address that is\nderived from the hash of the file.\nThis ensures that a file can't be overridden,\nand an end-user of the IPFS will receive the same file at a given address."),(0,i.kt)("h3",{id:"security"},"Security"),(0,i.kt)("p",null,"The IPFS gateway acts as an end-user of the IPFS\nand allows users of the gateway to access IPFS without connection to the P2P network.\nUsage of a gateway introduces potential risk for the users of that gateway provider.\nIn case of a compromise in the security of the provider, meta information such as IP address,\nUser-Agent and other of its users can be leaked.\nIf the provider servers are unavailable the node loses access through the gateway to the IPFS network."),(0,i.kt)("h3",{id:"status-sticker-usage"},"Status sticker usage"),(0,i.kt)("p",null,"When the app shows a sticker, the Status app makes an HTTP GET request to IPFS gateway using the hyperlink."),(0,i.kt)("p",null,"To send a sticker in chat, a user of Status should buy or install a sticker pack."),(0,i.kt)("p",null,"To be available for installation a Sticker Pack should be submitted to Sticker market by an author."),(0,i.kt)("h4",{id:"submit-a-sticker"},"Submit a sticker"),(0,i.kt)("p",null,"To submit a sticker pack, the author should upload all assets to IPFS.\nThen generate a payload including name, author, thumbnail,\npreview and a list of stickers in the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/edn-format/edn"},"EDN format"),". Following this structure:\n",(0,i.kt)("inlineCode",{parentName:"p"},'{meta {:name "Sticker pack name"\n :author "Author Name"\n :thumbnail "e30101701220602163b4f56c747333f43775fdcbe4e62d6a3e147b22aaf6097ce0143a6b2373"\n :preview "e30101701220ef54a5354b78ef82e542bd468f58804de71c8ec268da7968a1422909357f2456"\n :stickers [{:hash "e301017012207737b75367b8068e5bdd027d7b71a25138c83e155d1f0c9bc5c48ff158724495"}\n {:hash "e301017012201a9cdea03f27cda1aede7315f79579e160c7b2b6a2eb51a66e47a96f47fe5284"}]}}'),"\nAll asset fields, are contenthash fields as per ",(0,i.kt)("a",{parentName:"p",href:"https://eips.ethereum.org/EIPS/eip-1577"},"EIP 1577"),".\nThe node also uploads this payload to IPFS, and the node uses the IPFS address in the content field of the Sticker Market contract.\nSee ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/status-im/sticker-market/blob/651e88e5f38c690e57ecaad47f46b9641b8b1e27/docs/specification.md"},"Sticker Market spec")," for a detailed description of the contract."),(0,i.kt)("h4",{id:"install-a-sticker-pack"},"Install a sticker pack"),(0,i.kt)("p",null,"To install a sticker pack, the node fetches all sticker packs available in Sticker Market.\nThe node needs the following steps to fetch all sticker packs:"),(0,i.kt)("h4",{id:"1-get-total-number-of-sticker-packs"},"1. Get total number of sticker packs"),(0,i.kt)("p",null,"Call ",(0,i.kt)("inlineCode",{parentName:"p"},"packCount()")," on the sticker market contract, will return number of sticker pack registered as ",(0,i.kt)("inlineCode",{parentName:"p"},"uint256"),"."),(0,i.kt)("h4",{id:"2-get-sticker-pack-by-id"},"2. Get sticker pack by id"),(0,i.kt)("p",null,"ID's are represented as ",(0,i.kt)("inlineCode",{parentName:"p"},"uint256")," and are incremental from ",(0,i.kt)("inlineCode",{parentName:"p"},"0")," to total number of sticker packs in the contract,\nreceived in the previous step.\nTo get a sticker pack call ",(0,i.kt)("inlineCode",{parentName:"p"},"getPackData(sticker-pack-id)"),", the return type is ",(0,i.kt)("inlineCode",{parentName:"p"},'["bytes4[]" "address" "bool" "uint256" "uint256" "bytes"]'),"\nwhich represents the following fields: ",(0,i.kt)("inlineCode",{parentName:"p"},"[category owner mintable timestamp price contenthash]"),".\nPrice is the SNT value in wei set by sticker pack owner.\nThe contenthash is the IPFS address described in the ",(0,i.kt)("a",{parentName:"p",href:"#submit-a-sticker"},"submit description")," above.\nOther fields specification could be found in ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/status-im/sticker-market/blob/651e88e5f38c690e57ecaad47f46b9641b8b1e27/docs/specification.md"},"Sticker Market spec")),(0,i.kt)("h5",{id:"3-get-owned-sticker-packs"},"3. Get owned sticker packs"),(0,i.kt)("p",null,"The current Status app fetches owned sticker packs during the open of any sticker view\n(a screen which shows a sticker pack, or the list of sticker packs).\nTo get owned packs, get all owned tokens for the current account address,\nby calling ",(0,i.kt)("inlineCode",{parentName:"p"},"balanceOf(address)")," where address is the address for the current account.\nThis method returns a ",(0,i.kt)("inlineCode",{parentName:"p"},"uint256")," representing the count of available tokens. Using ",(0,i.kt)("inlineCode",{parentName:"p"},"tokenOfOwnerByIndex(address,uint256)")," method,\nwith the address of the user and ID in form of a ",(0,i.kt)("inlineCode",{parentName:"p"},"uint256"),"\nwhich is an incremented int from 0 to the total number of tokens, gives the token id.\nTo get the sticker pack id from a token call",(0,i.kt)("inlineCode",{parentName:"p"},"tokenPackId(uint256)")," where ",(0,i.kt)("inlineCode",{parentName:"p"},"uint256")," is the token id.\nThis method will return an ",(0,i.kt)("inlineCode",{parentName:"p"},"uint256")," which is the id of the owned sticker pack."),(0,i.kt)("h5",{id:"4-buy-a-sticker-pack"},"4. Buy a sticker pack"),(0,i.kt)("p",null,"To buy a sticker pack call ",(0,i.kt)("inlineCode",{parentName:"p"},"approveAndCall(address,uint256,bytes)"),"\nwhere ",(0,i.kt)("inlineCode",{parentName:"p"},"address")," is the address of buyer,",(0,i.kt)("inlineCode",{parentName:"p"},"uint256")," is the price and third parameters ",(0,i.kt)("inlineCode",{parentName:"p"},"bytes")," is the callback called if approved.\nIn the callback, call ",(0,i.kt)("inlineCode",{parentName:"p"},"buyToken(uint256,address,uint256)"),", first parameter is sticker pack id, second buyers address, and the last is the price."),(0,i.kt)("h2",{id:"copyright"},"Copyright"),(0,i.kt)("p",null,"Copyright and related rights waived via ",(0,i.kt)("a",{parentName:"p",href:"https://creativecommons.org/publicdomain/zero/1.0/"},"CC0"),"."),(0,i.kt)("h2",{id:"references"},"References"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://eips.ethereum.org/EIPS/eip-721"},"ERC721 Token Standard")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://infura.io/"},"Infura")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://github.com/edn-format/edn"},"EDN Format")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://eips.ethereum.org/EIPS/eip-1577"},"EIP 1577")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://github.com/status-im/sticker-market/blob/651e88e5f38c690e57ecaad47f46b9641b8b1e27/docs/specification.md"},"Sticker Market Specification"))))}d.isMDXComponent=!0},3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>u});var r=a(67294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function n(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function s(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?n(Object(a),!0).forEach((function(t){i(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):n(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function o(e,t){if(null==e)return{};var a,r,i=function(e,t){if(null==e)return{};var a,r,i={},n=Object.keys(e);for(r=0;r<n.length;r++)a=n[r],t.indexOf(a)>=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(r=0;r<n.length;r++)a=n[r],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var c=r.createContext({}),l=function(e){var t=r.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},k=r.forwardRef((function(e,t){var a=e.components,i=e.mdxType,n=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),k=l(a),u=i,h=k["".concat(c,".").concat(u)]||k[u]||d[u]||n;return a?r.createElement(h,s(s({ref:t},p),{},{components:a})):r.createElement(h,s({ref:t},p))}));function u(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var n=a.length,s=new Array(n);s[0]=k;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o.mdxType="string"==typeof e?e:i,s[1]=o;for(var l=2;l<n;l++)s[l]=a[l];return r.createElement.apply(null,s)}return r.createElement.apply(null,a)}k.displayName="MDXCreateElement"}}]);