Page Not Found
We could not find what you were looking for.
Please contact the owner of the site that linked you to the original URL and let them know their link is broken.
diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..f262aa8f --- /dev/null +++ b/404.html @@ -0,0 +1,13 @@ + + +
+ + +We could not find what you were looking for.
Please contact the owner of the site that linked you to the original URL and let them know their link is broken.
["'])(?.*?)\1/,ae=/\{(? [\d,-]+)\}/,oe={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}},ie={...oe,lua:{start:"--",end:""},wasm:{start:"\\;\\;",end:""},tex:{start:"%",end:""},vb:{start:"['\u2018\u2019]",end:""},vbnet:{start:"(?:_\\s*)?['\u2018\u2019]",end:""},rem:{start:"[Rr][Ee][Mm]\\b",end:""},f90:{start:"!",end:""},ml:{start:"\\(\\*",end:"\\*\\)"},cobol:{start:"\\*>",end:""}},re=Object.keys(oe);function le(e,t){const n=e.map((e=>{const{start:n,end:s}=ie[e];return`(?:${n}\\s*(${t.flatMap((e=>[e.line,e.block?.start,e.block?.end].filter(Boolean))).join("|")})\\s*${s})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function ce(e,t){let n=e.replace(/\n$/,"");const{language:s,magicComments:a,metastring:o}=t;if(o&&ae.test(o)){const e=o.match(ae).groups.range;if(0===a.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${o}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const t=a[0].className,s=ne()(e).filter((e=>e>0)).map((e=>[e-1,[t]]));return{lineClassNames:Object.fromEntries(s),code:n}}if(void 0===s)return{lineClassNames:{},code:n};const i=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return le(["js","jsBlock"],t);case"jsx":case"tsx":return le(["js","jsBlock","jsx"],t);case"html":return le(["js","jsBlock","html"],t);case"python":case"py":case"bash":return le(["bash"],t);case"markdown":case"md":return le(["html","jsx","bash"],t);case"tex":case"latex":case"matlab":return le(["tex"],t);case"lua":case"haskell":case"sql":return le(["lua"],t);case"wasm":return le(["wasm"],t);case"vb":case"vba":case"visual-basic":return le(["vb","rem"],t);case"vbnet":return le(["vbnet","rem"],t);case"batch":return le(["rem"],t);case"basic":return le(["rem","f90"],t);case"fsharp":return le(["js","ml"],t);case"ocaml":case"sml":return le(["ml"],t);case"fortran":return le(["f90"],t);case"cobol":return le(["cobol"],t);default:return le(re,t)}}(s,a),r=n.split("\n"),l=Object.fromEntries(a.map((e=>[e.className,{start:0,range:""}]))),c=Object.fromEntries(a.filter((e=>e.line)).map((e=>{let{className:t,line:n}=e;return[n,t]}))),d=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.start,t]}))),u=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.end,t]})));for(let h=0;h void 0!==e));c[t]?l[c[t]].range+=`${h},`:d[t]?l[d[t]].start=h:u[t]&&(l[u[t]].range+=`${l[u[t]].start}-${h-1},`),r.splice(h,1)}n=r.join("\n");const m={};return Object.entries(l).forEach((e=>{let[t,{range:n}]=e;ne()(n).forEach((e=>{m[e]??=[],m[e].push(t)}))})),{lineClassNames:m,code:n}}const de={codeBlockContainer:"codeBlockContainer_om3b"};function ue(e){let{as:t,...n}=e;const s=function(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach((e=>{let[s,a]=e;const o=t[s];o&&"string"==typeof a&&(n[o]=a)})),n}(ee());return(0,i.jsx)(t,{...n,style:s,className:(0,l.A)(n.className,de.codeBlockContainer,x.G.common.codeBlock)})}const me={codeBlockContent:"codeBlockContent_wy8a",codeBlockTitle:"codeBlockTitle_ghPa",codeBlock:"codeBlock_Ml9p",codeBlockStandalone:"codeBlockStandalone_kuj2",codeBlockLines:"codeBlockLines_nvaI",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_jeec",buttonGroup:"buttonGroup___rI"};function he(e){let{children:t,className:n}=e;return(0,i.jsx)(ue,{as:"pre",tabIndex:0,className:(0,l.A)(me.codeBlockStandalone,"thin-scrollbar",n),children:(0,i.jsx)("code",{className:me.codeBlockLines,children:t})})}var fe=n(1495);const pe={attributes:!0,characterData:!0,childList:!0,subtree:!0};function be(e,t){const[n,a]=(0,s.useState)(),o=(0,s.useCallback)((()=>{a(e.current?.closest("[role=tabpanel][hidden]"))}),[e,a]);(0,s.useEffect)((()=>{o()}),[o]),function(e,t,n){void 0===n&&(n=pe);const a=(0,fe._q)(t),o=(0,fe.Be)(n);(0,s.useEffect)((()=>{const t=new MutationObserver(a);return e&&t.observe(e,o),()=>t.disconnect()}),[e,a,o])}(n,(e=>{e.forEach((e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),o())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}var xe=n(3477);const ge={codeLine:"codeLine_rz2B",codeLineNumber:"codeLineNumber_O_eG",codeLineContent:"codeLineContent_GZzm"};function ve(e){let{line:t,classNames:n,showLineNumbers:s,getLineProps:a,getTokenProps:o}=e;1===t.length&&"\n"===t[0].content&&(t[0].content="");const r=a({line:t,className:(0,l.A)(n,s&&ge.codeLine)}),c=t.map(((e,t)=>(0,i.jsx)("span",{...o({token:e})},t)));return(0,i.jsxs)("span",{...r,children:[s?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("span",{className:ge.codeLineNumber}),(0,i.jsx)("span",{className:ge.codeLineContent,children:c})]}):c,(0,i.jsx)("br",{})]})}function je(e){return(0,i.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,i.jsx)("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"})})}function ke(e){return(0,i.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,i.jsx)("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"})})}const Ne={copyButtonCopied:"copyButtonCopied_BLhh",copyButtonIcons:"copyButtonIcons_AOAC",copyButtonIcon:"copyButtonIcon_KQr7",copyButtonSuccessIcon:"copyButtonSuccessIcon_UDIV"};function ye(e){let{code:t,className:n}=e;const[a,o]=(0,s.useState)(!1),r=(0,s.useRef)(void 0),c=(0,s.useCallback)((()=>{!function(e,t){let{target:n=document.body}=void 0===t?{}:t;if("string"!=typeof e)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof e}\`.`);const s=document.createElement("textarea"),a=document.activeElement;s.value=e,s.setAttribute("readonly",""),s.style.contain="strict",s.style.position="absolute",s.style.left="-9999px",s.style.fontSize="12pt";const o=document.getSelection(),i=o.rangeCount>0&&o.getRangeAt(0);n.append(s),s.select(),s.selectionStart=0,s.selectionEnd=e.length;let r=!1;try{r=document.execCommand("copy")}catch{}s.remove(),i&&(o.removeAllRanges(),o.addRange(i)),a&&a.focus()}(t),o(!0),r.current=window.setTimeout((()=>{o(!1)}),1e3)}),[t]);return(0,s.useEffect)((()=>()=>window.clearTimeout(r.current)),[]),(0,i.jsx)("button",{type:"button","aria-label":a?(0,d.T)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,d.T)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,d.T)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,l.A)("clean-btn",n,Ne.copyButton,a&&Ne.copyButtonCopied),onClick:c,children:(0,i.jsxs)("span",{className:Ne.copyButtonIcons,"aria-hidden":"true",children:[(0,i.jsx)(je,{className:Ne.copyButtonIcon}),(0,i.jsx)(ke,{className:Ne.copyButtonSuccessIcon})]})})}function Ce(e){return(0,i.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,i.jsx)("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"})})}const we={wordWrapButtonIcon:"wordWrapButtonIcon_w6Zv",wordWrapButtonEnabled:"wordWrapButtonEnabled_b9gR"};function Ae(e){let{className:t,onClick:n,isEnabled:s}=e;const a=(0,d.T)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return(0,i.jsx)("button",{type:"button",onClick:n,className:(0,l.A)("clean-btn",t,s&&we.wordWrapButtonEnabled),"aria-label":a,title:a,children:(0,i.jsx)(Ce,{className:we.wordWrapButtonIcon,"aria-hidden":"true"})})}function Le(e){let{children:t,className:n="",metastring:a,title:o,showLineNumbers:r,language:c}=e;const{prism:{defaultLanguage:d,magicComments:u}}=(0,E.p)(),m=function(e){return e?.toLowerCase()}(c??function(e){const t=e.split(" ").find((e=>e.startsWith("language-")));return t?.replace(/language-/,"")}(n)??d),h=ee(),f=function(){const[e,t]=(0,s.useState)(!1),[n,a]=(0,s.useState)(!1),o=(0,s.useRef)(null),i=(0,s.useCallback)((()=>{const n=o.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t((e=>!e))}),[o,e]),r=(0,s.useCallback)((()=>{const{scrollWidth:e,clientWidth:t}=o.current,n=e>t||o.current.querySelector("code").hasAttribute("style");a(n)}),[o]);return be(o,r),(0,s.useEffect)((()=>{r()}),[e,r]),(0,s.useEffect)((()=>(window.addEventListener("resize",r,{passive:!0}),()=>{window.removeEventListener("resize",r)})),[r]),{codeBlockRef:o,isEnabled:e,isCodeScrollable:n,toggle:i}}(),p=function(e){return e?.match(se)?.groups.title??""}(a)||o,{lineClassNames:b,code:x}=ce(t,{metastring:a,language:m,magicComments:u}),g=r??function(e){return Boolean(e?.includes("showLineNumbers"))}(a);return(0,i.jsxs)(ue,{as:"div",className:(0,l.A)(n,m&&!n.includes(`language-${m}`)&&`language-${m}`),children:[p&&(0,i.jsx)("div",{className:me.codeBlockTitle,children:p}),(0,i.jsxs)("div",{className:me.codeBlockContent,children:[(0,i.jsx)(xe.f4,{theme:h,code:x,language:m??"text",children:e=>{let{className:t,style:n,tokens:s,getLineProps:a,getTokenProps:o}=e;return(0,i.jsx)("pre",{tabIndex:0,ref:f.codeBlockRef,className:(0,l.A)(t,me.codeBlock,"thin-scrollbar"),style:n,children:(0,i.jsx)("code",{className:(0,l.A)(me.codeBlockLines,g&&me.codeBlockLinesWithNumbering),children:s.map(((e,t)=>(0,i.jsx)(ve,{line:e,getLineProps:a,getTokenProps:o,classNames:b[t],showLineNumbers:g},t)))})})}}),(0,i.jsxs)("div",{className:me.buttonGroup,children:[(f.isEnabled||f.isCodeScrollable)&&(0,i.jsx)(Ae,{className:me.codeButton,onClick:()=>f.toggle(),isEnabled:f.isEnabled}),(0,i.jsx)(ye,{className:me.codeButton,code:x})]})]})]})}function Ee(e){let{children:t,...n}=e;const a=(0,Q.A)(),o=function(e){return s.Children.toArray(e).some((e=>(0,s.isValidElement)(e)))?e:Array.isArray(e)?e.join(""):e}(t),r="string"==typeof o?Le:he;return(0,i.jsx)(r,{...n,children:o},String(a))}function Be(e){return(0,i.jsx)("code",{...e})}var Te=n(1843);const Se={details:"details_YB2c",isBrowser:"isBrowser_KW2d",collapsibleContent:"collapsibleContent_w384"};function _e(e){return!!e&&("SUMMARY"===e.tagName||_e(e.parentElement))}function Ie(e,t){return!!e&&(e===t||Ie(e.parentElement,t))}function Me(e){let{summary:t,children:n,...a}=e;(0,Te.A)().collectAnchor(a.id);const o=(0,Q.A)(),r=(0,s.useRef)(null),{collapsed:c,setCollapsed:d}=(0,L.u)({initialState:!a.open}),[u,m]=(0,s.useState)(a.open),h=s.isValidElement(t)?t:(0,i.jsx)("summary",{children:t??"Details"});return(0,i.jsxs)("details",{...a,ref:r,open:u,"data-collapsed":c,className:(0,l.A)(Se.details,o&&Se.isBrowser,a.className),onMouseDown:e=>{_e(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;_e(t)&&Ie(t,r.current)&&(e.preventDefault(),c?(d(!1),m(!0)):d(!0))},children:[h,(0,i.jsx)(L.N,{lazy:!1,collapsed:c,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{d(e),m(!e)},children:(0,i.jsx)("div",{className:Se.collapsibleContent,children:n})})]})}const Re={details:"details_FSj2"},He="alert alert--info";function Ue(e){let{...t}=e;return(0,i.jsx)(Me,{...t,className:(0,l.A)(He,Re.details,t.className)})}function $e(e){const t=s.Children.toArray(e.children),n=t.find((e=>s.isValidElement(e)&&"summary"===e.type)),a=(0,i.jsx)(i.Fragment,{children:t.filter((e=>e!==n))});return(0,i.jsx)(Ue,{...e,summary:n,children:a})}function ze(e){return(0,i.jsx)(Y.A,{...e})}const Oe={containsTaskList:"containsTaskList_njjY"};function De(e){if(void 0!==e)return(0,l.A)(e,e?.includes("contains-task-list")&&Oe.containsTaskList)}const Ve={img:"img_Aha3"};function Fe(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=s.Children.toArray(e),n=t.find((e=>s.isValidElement(e)&&"mdxAdmonitionTitle"===e.type)),a=t.filter((e=>e!==n)),o=n?.props.children;return{mdxAdmonitionTitle:o,rest:a.length>0?(0,i.jsx)(i.Fragment,{children:a}):null}}(e.children),a=e.title??t;return{...e,...a&&{title:a},children:n}}const Ge={admonition:"admonition_Xxwy",admonitionHeading:"admonitionHeading_Hz5a",admonitionIcon:"admonitionIcon_u47d",admonitionContent:"admonitionContent_CGmw"};function Pe(e){let{type:t,className:n,children:s}=e;return(0,i.jsx)("div",{className:(0,l.A)(x.G.common.admonition,x.G.common.admonitionType(t),Ge.admonition,n),children:s})}function We(e){let{icon:t,title:n}=e;return(0,i.jsxs)("div",{className:Ge.admonitionHeading,children:[(0,i.jsx)("span",{className:Ge.admonitionIcon,children:t}),n]})}function qe(e){let{children:t}=e;return t?(0,i.jsx)("div",{className:Ge.admonitionContent,children:t}):null}function Ze(e){const{type:t,icon:n,title:s,children:a,className:o}=e;return(0,i.jsxs)(Pe,{type:t,className:o,children:[s||n?(0,i.jsx)(We,{title:s,icon:n}):null,(0,i.jsx)(qe,{children:a})]})}function Ye(e){return(0,i.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,i.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const Ke={icon:(0,i.jsx)(Ye,{}),title:(0,i.jsx)(d.A,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function Je(e){return(0,i.jsx)(Ze,{...Ke,...e,className:(0,l.A)("alert alert--secondary",e.className),children:e.children})}function Qe(e){return(0,i.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,i.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const Xe={icon:(0,i.jsx)(Qe,{}),title:(0,i.jsx)(d.A,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function et(e){return(0,i.jsx)(Ze,{...Xe,...e,className:(0,l.A)("alert alert--success",e.className),children:e.children})}function tt(e){return(0,i.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,i.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const nt={icon:(0,i.jsx)(tt,{}),title:(0,i.jsx)(d.A,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function st(e){return(0,i.jsx)(Ze,{...nt,...e,className:(0,l.A)("alert alert--info",e.className),children:e.children})}function at(e){return(0,i.jsx)("svg",{viewBox:"0 0 16 16",...e,children:(0,i.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const ot={icon:(0,i.jsx)(at,{}),title:(0,i.jsx)(d.A,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function it(e){return(0,i.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,i.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const rt={icon:(0,i.jsx)(it,{}),title:(0,i.jsx)(d.A,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const lt={icon:(0,i.jsx)(at,{}),title:(0,i.jsx)(d.A,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const ct={...{note:Je,tip:et,info:st,warning:function(e){return(0,i.jsx)(Ze,{...ot,...e,className:(0,l.A)("alert alert--warning",e.className),children:e.children})},danger:function(e){return(0,i.jsx)(Ze,{...rt,...e,className:(0,l.A)("alert alert--danger",e.className),children:e.children})}},...{secondary:e=>(0,i.jsx)(Je,{title:"secondary",...e}),important:e=>(0,i.jsx)(st,{title:"important",...e}),success:e=>(0,i.jsx)(et,{title:"success",...e}),caution:function(e){return(0,i.jsx)(Ze,{...lt,...e,className:(0,l.A)("alert alert--warning",e.className),children:e.children})}}};function dt(e){const t=Fe(e),n=(s=t.type,ct[s]||(console.warn(`No admonition component found for admonition type "${s}". Using Info as fallback.`),ct.info));var s;return(0,i.jsx)(n,{...t})}var ut=n(8525);const mt={Head:J.A,details:$e,Details:$e,code:function(e){return function(e){return void 0!==e.children&&s.Children.toArray(e.children).every((e=>"string"==typeof e&&!e.includes("\n")))}(e)?(0,i.jsx)(Be,{...e}):(0,i.jsx)(Ee,{...e})},a:function(e){return(0,i.jsx)(u.A,{...e})},pre:function(e){return(0,i.jsx)(i.Fragment,{children:e.children})},ul:function(e){return(0,i.jsx)("ul",{...e,className:De(e.className)})},li:function(e){return(0,Te.A)().collectAnchor(e.id),(0,i.jsx)("li",{...e})},img:function(e){return(0,i.jsx)("img",{decoding:"async",loading:"lazy",...e,className:(t=e.className,(0,l.A)(t,Ve.img))});var t},h1:e=>(0,i.jsx)(ze,{as:"h1",...e}),h2:e=>(0,i.jsx)(ze,{as:"h2",...e}),h3:e=>(0,i.jsx)(ze,{as:"h3",...e}),h4:e=>(0,i.jsx)(ze,{as:"h4",...e}),h5:e=>(0,i.jsx)(ze,{as:"h5",...e}),h6:e=>(0,i.jsx)(ze,{as:"h6",...e}),admonition:dt,mermaid:ut.A};function ht(e){let{children:t}=e;return(0,i.jsx)(K.x,{components:mt,children:t})}function ft(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=(0,o.u)();return t.hide_title||void 0!==n?null:e.title}();return(0,i.jsxs)("div",{className:(0,l.A)(x.G.docs.docMarkdown,"markdown"),children:[n&&(0,i.jsx)("header",{children:(0,i.jsx)(Y.A,{as:"h1",children:n})}),(0,i.jsx)(ht,{children:t})]})}var pt=n(3766),bt=n(428),xt=n(1958);function gt(e){return(0,i.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,i.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const vt={breadcrumbHomeIcon:"breadcrumbHomeIcon_jWVc"};function jt(){const e=(0,xt.Ay)("/");return(0,i.jsx)("li",{className:"breadcrumbs__item",children:(0,i.jsx)(u.A,{"aria-label":(0,d.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,i.jsx)(gt,{className:vt.breadcrumbHomeIcon})})})}const kt={breadcrumbsContainer:"breadcrumbsContainer_SGes"};function Nt(e){let{children:t,href:n,isLast:s}=e;const a="breadcrumbs__link";return s?(0,i.jsx)("span",{className:a,itemProp:"name",children:t}):n?(0,i.jsx)(u.A,{className:a,href:n,itemProp:"item",children:(0,i.jsx)("span",{itemProp:"name",children:t})}):(0,i.jsx)("span",{className:a,children:t})}function yt(e){let{children:t,active:n,index:s,addMicrodata:a}=e;return(0,i.jsxs)("li",{...a&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,l.A)("breadcrumbs__item",{"breadcrumbs__item--active":n}),children:[t,(0,i.jsx)("meta",{itemProp:"position",content:String(s+1)})]})}function Ct(){const e=(0,pt.OF)(),t=(0,bt.Dt)();return e?(0,i.jsx)("nav",{className:(0,l.A)(x.G.docs.docBreadcrumbs,kt.breadcrumbsContainer),"aria-label":(0,d.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,i.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[t&&(0,i.jsx)(jt,{}),e.map(((t,n)=>{const s=n===e.length-1,a="category"===t.type&&t.linkUnlisted?void 0:t.href;return(0,i.jsx)(yt,{active:s,index:n,addMicrodata:!!a,children:(0,i.jsx)(Nt,{href:a,isLast:s,children:t.label})},n)}))]})}):null}function wt(){return(0,i.jsx)(d.A,{id:"theme.unlistedContent.title",description:"The unlisted content banner title",children:"Unlisted page"})}function At(){return(0,i.jsx)(d.A,{id:"theme.unlistedContent.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function Lt(){return(0,i.jsx)(J.A,{children:(0,i.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function Et(e){let{className:t}=e;return(0,i.jsx)(dt,{type:"caution",title:(0,i.jsx)(wt,{}),className:(0,l.A)(t,x.G.common.unlistedBanner),children:(0,i.jsx)(At,{})})}function Bt(e){return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(Lt,{}),(0,i.jsx)(Et,{...e})]})}const Tt={docItemContainer:"docItemContainer_mlrF",docItemCol:"docItemCol_UIRF"};function St(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=(0,o.u)(),n=(0,c.l)(),s=e.hide_table_of_contents,a=!s&&t.length>0;return{hidden:s,mobile:a?(0,i.jsx)(F,{}):void 0,desktop:!a||"desktop"!==n&&"ssr"!==n?void 0:(0,i.jsx)(Z,{})}}(),{metadata:{unlisted:s}}=(0,o.u)();return(0,i.jsxs)("div",{className:"row",children:[(0,i.jsxs)("div",{className:(0,l.A)("col",!n.hidden&&Tt.docItemCol),children:[s&&(0,i.jsx)(Bt,{}),(0,i.jsx)(C,{}),(0,i.jsxs)("div",{className:Tt.docItemContainer,children:[(0,i.jsxs)("article",{children:[(0,i.jsx)(Ct,{}),(0,i.jsx)(w,{}),n.mobile,(0,i.jsx)(ft,{children:t}),(0,i.jsx)(A.A,{})]}),(0,i.jsx)(f,{})]})]}),n.desktop&&(0,i.jsx)("div",{className:"col col--3",children:n.desktop})]})}function _t(e){const t=`docs-doc-id-${e.content.metadata.id}`,n=e.content;return(0,i.jsx)(o._,{content:e.content,children:(0,i.jsxs)(a.e3,{className:t,children:[(0,i.jsx)(r,{}),(0,i.jsx)(St,{children:(0,i.jsx)(n,{})})]})})}},9336:(e,t,n)=>{"use strict";n.d(t,{_:()=>r,u:()=>l});var s=n(758),a=n(1495),o=n(6070);const i=s.createContext(null);function r(e){let{children:t,content:n}=e;const a=function(e){return(0,s.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return(0,o.jsx)(i.Provider,{value:a,children:t})}function l(){const e=(0,s.useContext)(i);if(null===e)throw new a.dV("DocProvider");return e}},4809:(e,t)=>{function n(e){let t,n=[];for(let s of e.split(",").map((e=>e.trim())))if(/^-?\d+$/.test(s))n.push(parseInt(s,10));else if(t=s.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,s,a,o]=t;if(s&&o){s=parseInt(s),o=parseInt(o);const e=s {"use strict";n.d(t,{D1:()=>G,MB:()=>P,l6:()=>$,vN:()=>_});var s=n(758),a=n(6070),o=n(8143);function i(e,t){if(!e||"$auto"===e)return t?.toString()||(typeof window<"u"?window.location.href:"/");if("$path"===e){"string"==typeof t&&(t=new URL(t));let e=t||(typeof window<"u"?window.location:void 0);return e?`${e.origin}${e.pathname}`:"/"}return e}var r="fbs-store";function l(e){return"contentId"in e?e.contentId:`${e.contentSetId}/${i(e.key)}`}var c,d,u=class{constructor(e){if(this.feelbacks=void 0,e??="local",typeof window>"u"&&(e="memory"),"local"===e)this.storage=window.localStorage;else if("session"===e)this.storage=window.sessionStorage;else{let e=()=>{};this.storage={getItem:e,setItem:e,removeItem:e,clear:e,key:e,length:0}}this.load()}add(e){let t=l(e.target),n=(this.feelbacks??=[]).findIndex((e=>e.key===t));n>=0&&this.feelbacks.splice(n,1),this.feelbacks.push({key:t,value:e.value,expire:e.expireIn&&e.expireIn>0?Math.floor(Date.now()/1e3)+e.expireIn:void 0,feelbackId:e.feelbackId,revokeToken:e.revokable?.token,revokeExpire:e.revokable?.expireAt&&Math.floor(new Date(e.revokable.expireAt).getTime()/1e3)||void 0}),this.save()}clear(){this.feelbacks?.splice(0,this.feelbacks.length),this.storage.removeItem(r)}remove(e){let t="string"==typeof e?this.feelbacks?.findIndex((t=>t.feelbackId===e)):(e=l(e),this.feelbacks?.findIndex((t=>t.key===e)));void 0!==t&&t>=0&&(this.feelbacks.splice(t,1),this.save())}getValue(e){return this.getFeelback(e)?.value}isRevokable(e){return!!this.getRevocable(e)}getRevocable(e){let t=this.getFeelback(e);if(t&&t.revokeToken&&!(t.revokeExpire&&t.revokeExpire !e.expire||e.expire>Date.now()/1e3)),t.length!==this.feelbacks.length&&this.save()}save(){try{this.storage.setItem(r,JSON.stringify(this.feelbacks))}catch{}}getFeelback(e){let t="string"==typeof e?this.feelbacks?.find((t=>t.feelbackId===e)):(e=l(e),this.feelbacks?.find((t=>t.key===e)));if(!(t&&t.expire&&t.expire =400)throw new Error("[feelback] API error");if(204!==e.status)return await e.json()}var f={get:async function(e,...t){return t.length>0&&(e=`${e}?$p=${JSON.stringify(t)}`),await h(fetch(e,{method:"GET"}))},post:async function(e,...t){return await h(fetch(e,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)}))}},p="https://api.feelback.dev/v0";var b=(0,s.createContext)(void 0);function x(){return(0,s.useContext)(b)}var g=()=>{let e=(0,s.useRef)(!1);return(0,s.useEffect)((()=>(e.current=!0,()=>{e.current=!1})),[]),()=>e.current};function v(e=5e3,t,n){(0,s.useEffect)((()=>{if(t)return function(e,t){let n=setTimeout(t,e);return()=>clearTimeout(n)}(e,(()=>n(t)))}),[t])}function j(e=5e3,t=!1){let n=(0,s.useRef)(t),[a,o]=(0,s.useState)(),i=(0,s.useCallback)((()=>r(n.current)),[]),r=(0,s.useCallback)((e=>o(e??!0)),[]);return v(e,a,i),{value:a,set:r,reset:i}}function k(e,t){let n=(0,s.useRef)(null);return(0,s.useEffect)((()=>{if(e&&t){let e=e=>{(!e.target||!n.current?.contains(e.target))&&(t(),e.stopPropagation(),e.preventDefault())};return document.addEventListener("click",e,{capture:!0}),()=>document.removeEventListener("click",e,{capture:!0})}}),[e]),n}var N={data:void 0,isLoading:!1,isCompleted:!1,isSuccess:!1,isError:!1,error:void 0};function y(e,t,n){let a=(0,s.useRef)(0),o=g(),i=!!n?.paused,r=!!t&&!i,[l,c]=(0,s.useReducer)(C,r,(e=>({...N,isLoading:e})));async function d(...t){let n=++a.current;try{l.isLoading||c({type:"LOADING"});let s=await e(...t);return o()&&n===a.current&&c({type:"SUCCESS",data:s}),C(l,{type:"SUCCESS",data:s})}catch(s){return o()&&n===a.current&&c({type:"ERROR",error:s}),C(l,{type:"ERROR",error:s})}}return(0,s.useEffect)((()=>{!i&&t&&d()}),[i,...t||[]]),{...l,call:d,exec:async(...e)=>{let t=await d(...e);if(t.error)throw t.error;return t.data},reset:()=>{c({type:"RESET"})}}}function C(e,t){switch(t.type){case"LOADING":return{...N,isLoading:!0,data:e.data};case"SUCCESS":return{...N,isCompleted:!0,isSuccess:!0,data:t.data};case"ERROR":return{...N,isCompleted:!0,error:t.error,isError:!0};case"RESET":return{...N};default:throw new Error("unknown action")}}function w(){let e=(0,s.useRef)("");return e.current||(e.current="i"+Math.random().toString().substring(2)),e.current}function A(e){if("function"==typeof e)return(0,s.createElement)(e);if("object"==typeof e&&"text"in e)return(0,s.createElement)(s.Fragment,void 0,[e.text]);if((0,s.isValidElement)(e))return e;throw console.error("Invalid icon",e),new Error("Invalid icon")}function L(e,t){return e&&t?function(){e.apply(this,arguments),t.apply(this,arguments)}:e||t}function E(e){let{count:t=!1,isActive:n=!1,isDisabled:s=!1,label:o,title:i,icon:r,onClick:l}=e;return(0,a.jsxs)("button",{title:i,className:`feelback-btn ${s?"disabled":""} ${n?"active":""}`,onClick:l,children:[r&&(Array.isArray(r)?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"feelback-icon inactive",children:A(r[0])}),(0,a.jsx)("span",{className:"feelback-icon active",children:A(r[1])})]}):(0,a.jsx)("span",{className:"feelback-icon",children:A(r)})),o&&(0,a.jsx)("span",{className:"label",children:o}),!1!==t&&(0,a.jsx)("span",{className:"feelback-count",children:t})]})}function B(e){let{active:t,showCount:n=!1,showLabels:s=!1,showTitle:o=!s,hideZero:i=!1,hideZeroCount:r=!0,isDisabled:l=!1,items:c,counts:d,onClick:u}=e;return(0,a.jsx)("div",{className:"feelback-buttons"+(n&&c.length>1?" with-count":""),children:c.map((({value:e,icon:c,title:m},h)=>{let f=d?.[h]||(t===e?1:0);return i&&f<=0?null:(0,a.jsx)(E,{title:o&&m||void 0,label:s&&m||void 0,icon:c,count:n&&f||(r?void 0:0),isDisabled:l,isActive:t===e,onClick:()=>u?.(e)},e)}))})}function T(e){let{group:t,value:n,label:s,description:o,checked:i,onSelected:r}=e,l=`radio-${w()}`;return(0,a.jsxs)("div",{className:"feelback-radio-item",children:[(0,a.jsx)("input",{id:l,name:t,type:"radio",value:n,checked:i,onChange:e=>e.target.checked?r?.():void 0}),(0,a.jsxs)("div",{className:"feelback-radio-side",children:[s&&(0,a.jsx)("label",{htmlFor:l,children:s}),o&&(0,a.jsx)("span",{className:"feelback-text",children:o})]})]})}function S(e){let{active:t,isDisabled:n=!1,items:s,onRenderAddon:o,onSelected:i}=e,r=`rg-${w()}`;return(0,a.jsx)("fieldset",{className:"feelback-radio-group",children:s.map((e=>(0,a.jsxs)("div",{className:"feelback-radio-item-wrap",children:[(0,a.jsx)(T,{group:r,checked:t===e.value,value:e.value,label:e.title,description:e.description,onSelected:()=>i?.(e.value)}),o?.({item:e,isSelected:t===e.value,isDisabled:n})||null]},e.value)))})}function _(e){let{text:t,...n}=e;return(0,a.jsxs)("div",{className:"feelback-q",children:[t&&"string"==typeof t&&(0,a.jsx)("span",{className:"feelback-text",children:t}),t&&(0,s.isValidElement)(t)&&t,(0,a.jsx)(B,{...n})]})}function I(e){let{text:t}=e;return(0,a.jsx)("div",{className:"feelback-a",children:(0,a.jsx)("span",{className:"feelback-text",children:t})})}var M=(0,s.forwardRef)(((e,t)=>{let{className:n,layout:o,label:i="Send feedback",textAnswer:r="Thanks for your feedback",revokable:l=!0,onClose:c,onSuccess:d,children:u,...m}=e,{call:h,isSuccess:f}=O(m),{value:p,set:b}=j(1e3),x=({value:e,metadata:t})=>{b(!0),h(e,{metadata:t,revokable:l}).then((({isSuccess:t})=>{t&&d?.({...m,value:e})}))};return(0,a.jsxs)("div",{ref:t,className:"feelback-container"+(n?" "+n:""),style:{pointerEvents:p?"none":void 0},children:[!f&&(()=>{switch(o){case"button-switch":return(0,a.jsx)(R,{label:i,behavior:"remove-when-open",children:e=>(0,s.cloneElement)(u,{onSubmit:x,onCancel:e})});case"button-dialog":return(0,a.jsx)(R,{label:i,behavior:"disable-when-open",children:e=>(0,a.jsx)(H,{onClose:e,children:(0,s.cloneElement)(u,{onSubmit:x,onCancel:e})})});case"radio-group-dialog":return(0,a.jsx)(H,{onClose:c,children:(0,s.cloneElement)(u,{onSubmit:x,onCancel:L(u.props.onCancel,c)})});default:return(0,s.cloneElement)(u,{onSubmit:x})}})(),f&&(0,a.jsx)(I,{text:r})]})}));function R(e){let{label:t,behavior:n="remove-when-open",children:o}=e,[i,r]=(0,s.useState)(!1);return(0,a.jsxs)(a.Fragment,{children:[(!i||"remove-when-open"!==n)&&(0,a.jsx)("button",{className:"feelback-btn btn-action trigger-btn",disabled:i,onClick:()=>r(!0),children:t}),i&&o((()=>r(!1)))]})}function H(e){let{onClose:t,children:n}=e,i=k(!0,t);return(0,o.createPortal)((0,a.jsx)("div",{className:"feelback-style",children:(0,a.jsx)("div",{className:"dialog",children:(0,s.cloneElement)(n,{ref:i})})}),document.body)}var U=(0,s.forwardRef)(((e,t)=>{let{title:n="Send feedback",alignButton:s="right",showButton:o=!0,onCancel:i,onSubmit:r,onValidate:l,slots:c,children:d}=e;return(0,a.jsx)("div",{ref:t,className:"feelback-form",children:(0,a.jsxs)("div",{className:"content",children:[n&&(0,a.jsx)("span",{className:"feelback-text form-title",children:n}),d,o&&c?.BeforeFormButtons,o&&(0,a.jsxs)("div",{className:"form-buttons feelback-buttons "+("right"===s?"align-end":""),children:[(0,a.jsx)("button",{className:"feelback-btn btn-action",onClick:()=>{let e=l();void 0!==e&&r?.(e)},children:"Send"}),i&&(0,a.jsx)("button",{className:"feelback-btn btn-cancel",onClick:i,children:"Cancel"})]})]})})}));(0,s.forwardRef)(((e,t)=>{let{title:n="Send feedback",placeholder:o="Type your message",minLength:i,maxLength:r,withEmail:l,placeholderEmail:c="your@email.com"+(l&&"required"!==l?" (optional)":""),slots:d,onCancel:u,onSubmit:m}=e,h=(0,s.useRef)(null),f="required"===l,p=(0,s.useRef)(null);return(0,a.jsxs)(U,{slots:d,title:n,onCancel:u,onSubmit:m,ref:t,onValidate:()=>{let e=h.current?.value.trim()||void 0,t=p.current?.value?.trim()||void 0;if(e&&!(i&&i>0&&e.length{let{layout:n,title:o="Send feedback",active:i,tags:r,showLabels:l=!0,placeholder:c="Type your message",minLength:d,maxLength:u,withEmail:m,placeholderEmail:h="your@email.com"+(m&&"required"!==m?" (optional)":""),slots:f,onCancel:p,onSubmit:b}=e,x=!!d&&d>0,g=(0,s.useRef)(null),v="required"===m,j=(0,s.useRef)(null),[k,N]=(0,s.useState)("$auto"===i?r[0].value:i),y=(0,a.jsxs)(a.Fragment,{children:[f?.BeforeMessage,(0,a.jsx)("textarea",{ref:g,required:x,placeholder:c||void 0,minLength:d,maxLength:u})]}),C=m&&(0,a.jsxs)(a.Fragment,{children:[f?.BeforeEmail,(0,a.jsx)("input",{ref:j,type:"email",name:"email",required:v,placeholder:h||void 0})]});return(0,a.jsxs)(U,{onCancel:p,onSubmit:b,ref:t,onValidate:()=>{let e=g.current?.value?.trim()||void 0,t=j.current?.value?.trim()||void 0;if(k&&(!x||e&&!(e.length e&&(0,a.jsxs)(a.Fragment,{children:[y,C]})}),"reveal-message"===n&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(_,{text:o,items:r,showLabels:l,active:k,onClick:N}),k&&(0,a.jsxs)(a.Fragment,{children:[y,C]})]})]})}));function O(e){let t=x(),n=D(e);return y(((e,s)=>async function(e){let{endpoint:t=p,store:n="local",revokable:s=!0,value:a,metadata:o,expireIn:r=3600}=e,l="contentId"in e?{contentId:e.contentId}:{contentSetId:e.contentSetId,key:i(e.key)},c=n&&"none"!==n&&m(n)||void 0,d=s&&c?.getRevocable(l)||void 0,u=d?await f.post(`${t}/feelbacks/edit`,{...d,value:a}):await f.post(`${t}/feelbacks/create`,{...l,value:a,context:o,revokable:s});c?.add({...u,target:l,value:a,expireIn:r})}({endpoint:t?.endpoint,store:t?.store,...s,...n,value:e})))}function D(e){let t=(0,s.useRef)(e);return t.current!==e&&("contentId"in t.current&&"contentId"in e?t.current.contentId!==e.contentId&&t.current:"contentSetId"in t.current&&"contentSetId"in e?(t.current.contentSetId!==e.contentSetId||t.current.key!==e.key)&&(t.current=e):t.current=e),t.current}var V=e=>s.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 500 500",fill:"currentColor",width:"1em",height:"1em",...e},s.createElement("g",null,s.createElement("path",{d:"M172.7,309.1c0-7.4-3-14.6-8.3-19.9s-12.4-8.3-19.9-8.3H74.4c-10.1,0-19.3,5.4-24.4,14.1c-5.1,8.7-5,19.5,0,28.1 s14.3,14.1,24.4,14.1h70.2c7.4,0,14.6-3,19.9-8.3S172.7,316.5,172.7,309.1L172.7,309.1z"}),s.createElement("path",{d:"M102.5,449.5h70.2c10.1,0,19.3-5.4,24.4-14.1c5-8.6,5-19.5,0-28.1s-14.3-14.1-24.4-14.1h-70.2c-10.1,0-19.3,5.4-24.4,14.1 c-5,8.6-5,19.5,0,28.1C83.2,444.1,92.5,449.5,102.5,449.5z"}),s.createElement("path",{d:"M53.2,224.9h83.3c18.8,0,36.4-9.4,46.8-24.9l95.7-143.6h5c11.6,0,22.5,5.7,29.2,15.1s8.6,21.6,5,32.5l-25.4,76.5 c-1.3,3.7-0.6,7.9,1.8,11.2c2.3,3.2,6.2,5.2,10.1,5.2h65.6c14.7-0.3,28.8,6.3,37.9,17.7c5.3,6.6,8.6,14.3,9.8,22.6 c1.3,8.3,0.3,16.7-2.7,24.5l-47.6,118.7c-1.5,3.9-4.3,7.2-7.6,9.5c-3.5,2.3-7.5,3.6-11.6,3.6h-61.8l0,0c-7.1-0.3-14.2,2.2-19.7,7 c-5.4,4.6-8.9,11.2-9.9,18.4c-0.8,7.9,1.9,15.8,7.1,21.7c5.4,5.9,12.9,9.2,20.9,9.2h63.3c15.5,0,30.5-4.6,43.2-13.3 c12.8-8.6,22.7-20.9,28.5-35.2l47.6-118.8c12.8-32.1,8.8-68.5-11-97c-19.7-28.5-52.1-45.3-86.8-44.6h-4.6l5.7-17 c5.2-14.8,6.7-30.6,4.3-46.2c-3.6-21.6-14.8-41.3-31.5-55.5s-37.9-22.1-60-22h-20c-9.4,0-18.2,4.6-23.3,12.5l-104,156H54.5 c-7.1-0.1-14.1,2.3-19.6,7c-5.5,4.7-8.9,11.2-9.8,18.3c-0.8,7.9,1.9,15.8,7.1,21.7C37.8,221.4,45.2,224.9,53.2,224.9L53.2,224.9z"}))),F=e=>s.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 500 500",fill:"currentColor",width:"1em",height:"1em",...e},s.createElement("g",null,s.createElement("path",{d:"M327.3,190.8c0,7.3,2.9,14.6,8.3,19.8c5.3,5.3,12.4,8.3,19.8,8.3h70.2c10.1,0,19.4-5.4,24.4-14c5-8.6,5-19.5,0-28.1 c-5-8.6-14.3-14-24.4-14h-70.2c-7.3,0-14.6,2.9-19.8,8.3C330.3,176.3,327.3,183.4,327.3,190.8L327.3,190.8z"}),s.createElement("path",{d:"M397.5,50.4h-70.2c-10.1,0-19.4,5.4-24.4,14c-5,8.6-5,19.5,0,28.1c5,8.6,14.3,14,24.4,14h70.2c10.1,0,19.4-5.4,24.4-14 s5-19.5,0-28.1S407.6,50.4,397.5,50.4z"}),s.createElement("path",{d:"M446.8,275.1h-83.3c-18.8,0-36.3,9.5-46.8,25l-95.7,143.6h-5c-11.6,0-22.5-5.7-29.3-15.1c-6.8-9.4-8.6-21.6-5-32.5 l25.4-76.5c1.3-3.8,0.6-7.9-1.8-11.2c-2.3-3.2-6.2-5.1-10.1-5.1h-65.5c-14.7,0.3-28.7-6.3-38.1-17.7c-5.3-6.6-8.6-14.3-9.8-22.6 c-1.3-8.3-0.3-16.6,2.7-24.5l47.6-118.8c1.6-3.9,4.2-7.2,7.6-9.5c3.5-2.3,7.5-3.6,11.6-3.6h61.8l0,0c7.1,0.3,14.2-2.3,19.7-7 c5.4-4.7,8.9-11.3,9.9-18.4c0.7-7.9-1.9-15.8-7.1-21.7c-5.4-6-12.9-9.2-20.9-9.2h-63.3c-15.5,0-30.5,4.7-43.2,13.3 C95.7,72.4,85.8,84.7,80,99L32.4,217.8c-12.8,32.1-8.8,68.5,10.9,97.1c19.7,28.6,52.1,45.2,86.8,44.7h4.7l-5.7,17.1 c-5.1,14.9-6.7,30.6-4.2,46.2c3.6,21.6,14.9,41.3,31.5,55.4s37.9,21.8,59.8,21.7h20c9.5,0,18.2-4.7,23.3-12.5l104.1-156h82.1 c7.1,0.1,14-2.3,19.6-7c5.5-4.7,8.9-11.2,9.8-18.4c0.7-7.9-1.9-15.8-7.1-21.7C462.4,278.5,454.8,275.1,446.8,275.1L446.8,275.1z"}))),G=[{value:"y",icon:V,title:"Yes"},{value:"n",icon:F,title:"No"}],P=[{value:"idea",icon:{text:"\ud83d\udca1"},title:"Idea"},{value:"error",icon:{text:"\ud83d\udca5"},title:"Error"},{value:"other",icon:{text:"\ud83d\udcac"},title:"Other"}]},5710:(e,t,n)=>{"use strict";n.d(t,{R:()=>i,x:()=>r});var s=n(758);const a={},o=s.createContext(a);function i(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/70d114dd.a19536dd.js b/assets/js/70d114dd.a19536dd.js new file mode 100644 index 00000000..2e5c1058 --- /dev/null +++ b/assets/js/70d114dd.a19536dd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[12],{5283:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>d,toc:()=>l});var n=r(6070),o=r(5710);const i={id:"getting-started",title:"Getting started"},a=void 0,d={id:"explore/developers-quickstart/getting-started",title:"Getting started",description:"Before you start, make sure you are familiar with Calimero Terminology.",source:"@site/docs/01-explore/04-developers-quickstart/01-getting-started.mdx",sourceDirName:"01-explore/04-developers-quickstart",slug:"/explore/developers-quickstart/getting-started",permalink:"/explore/developers-quickstart/getting-started",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedAt:1718189423e3,sidebarPosition:1,frontMatter:{id:"getting-started",title:"Getting started"},sidebar:"tutorialSidebar",previous:{title:"Introduction",permalink:"/explore/intro"},next:{title:"Admin Dashboard",permalink:"/explore/developers-quickstart/admin-dashboard"}},s={},l=[{value:"Setup your local node",id:"setup-your-local-node",level:2},{value:"Prerequisites",id:"prerequisites",level:3},{value:"Setup",id:"setup",level:3},{value:"Initialize and start coordinator node (separate terminal)",id:"initialize-and-start-coordinator-node-separate-terminal",level:4},{value:"Initialize and start your node (separate terminal)",id:"initialize-and-start-your-node-separate-terminal",level:4},{value:"Congratulations on setting up your node!",id:"congratulations-on-setting-up-your-node",level:3}];function c(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(t.p,{children:["Before you start, make sure you are familiar with ",(0,n.jsx)(t.a,{href:"/learn/terminology",children:"Calimero Terminology"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"setup-your-local-node",children:"Setup your local node"}),"\n",(0,n.jsx)(t.h3,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsx)(t.p,{children:"Position in the root of the project and create a data folder for all configuration files."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-console",children:"$ mkdir data\n"})}),"\n",(0,n.jsx)(t.h3,{id:"setup",children:"Setup"}),"\n",(0,n.jsx)(t.p,{children:"Setup coordinator node used for managing the network transactions and peer nodes representing the network participants."}),"\n",(0,n.jsx)(t.h4,{id:"initialize-and-start-coordinator-node-separate-terminal",children:"Initialize and start coordinator node (separate terminal)"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"$ cargo run -p calimero-node -- --home data/coordinator init --server-port 2427 --swarm-port 2527\n$ cargo run -p calimero-node -- --home data/coordinator run --node-type coordinator\n"})}),"\n",(0,n.jsx)(t.h4,{id:"initialize-and-start-your-node-separate-terminal",children:"Initialize and start your node (separate terminal)"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"$ cargo run -p calimero-node -- --home data/node1 init --server-port 2428 --swarm-port 2528\n$ cargo run -p calimero-node -- --home data/node1 run\n"})}),"\n",(0,n.jsx)(t.p,{children:"Node is now initialized and ready for use."}),"\n",(0,n.jsx)(t.h3,{id:"congratulations-on-setting-up-your-node",children:"Congratulations on setting up your node!"}),"\n",(0,n.jsx)(t.p,{children:"Your next step is to add an authentication mechanism to your node by adding a decentralized identity."})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},5710:(e,t,r)=>{r.d(t,{R:()=>a,x:()=>d});var n=r(758);const o={},i=n.createContext(o);function a(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/73ad1aec.90fb7c8e.js b/assets/js/73ad1aec.90fb7c8e.js new file mode 100644 index 00000000..6d1f6d22 --- /dev/null +++ b/assets/js/73ad1aec.90fb7c8e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[420],{2770:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var i=t(6070),o=t(5710);const a={id:"client-node",title:"Client Node"},r=void 0,s={id:"learn/core-concepts/node/client-node",title:"Client Node",description:"Runtime",source:"@site/docs/02-learn/03-core-concepts/02-node/01-client-node.mdx",sourceDirName:"02-learn/03-core-concepts/02-node",slug:"/learn/core-concepts/node/client-node",permalink:"/learn/core-concepts/node/client-node",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedAt:1718189423e3,sidebarPosition:1,frontMatter:{id:"client-node",title:"Client Node"},sidebar:"tutorialSidebar",previous:{title:"Identity",permalink:"/learn/core-concepts/identity"},next:{title:"Runtime",permalink:"/learn/core-concepts/node/runtime"}},c={},l=[{value:"Runtime",id:"runtime",level:3},{value:"Recommendations for Developers: Thorough testing of applications in a controlled environment is advised before deploying them in production to ensure stability and security. Additionally, developers are encouraged to implement locked update rules to prevent unauthorized modifications to the application's behavior.",id:"recommendations-for-developers-thorough-testing-of-applications-in-a-controlled-environment-is-advised-before-deploying-them-in-production-to-ensure-stability-and-security-additionally-developers-are-encouraged-to-implement-locked-update-rules-to-prevent-unauthorized-modifications-to-the-applications-behavior",level:4},{value:"Storage",id:"storage",level:3},{value:"Encryption:",id:"encryption",level:3},{value:"Identity Management",id:"identity-management",level:3},{value:"Authentication",id:"authentication",level:3},{value:"Key Management",id:"key-management",level:3},{value:"Application Marketplace",id:"application-marketplace",level:3}];function d(e){const n={h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h3,{id:"runtime",children:"Runtime"}),"\n",(0,i.jsx)(n.p,{children:"Overview: The runtime environment of a client node in the Calimero Network is crucial for the execution of decentralized applications (DApps), particularly those compiled to WebAssembly (WASM)."}),"\n",(0,i.jsx)(n.p,{children:"Functionality:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"State Synchronization: Each node can download and synchronize the state with existing applications, ensuring that all nodes participating in a particular application network are consistent and up-to-date."}),"\n",(0,i.jsx)(n.li,{children:"Application Settings: Nodes can be configured with specific settings for each application, including which WASM modules to run, source URLs for fetching these modules, encryption protocols to be used, and more."}),"\n",(0,i.jsx)(n.li,{children:"Network Topology & Update Rules: Defines the structure of the network and how nodes communicate and update each other. Proper update rules are crucial for application security and integrity, particularly in a decentralized setting where trust is distributed."}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"recommendations-for-developers-thorough-testing-of-applications-in-a-controlled-environment-is-advised-before-deploying-them-in-production-to-ensure-stability-and-security-additionally-developers-are-encouraged-to-implement-locked-update-rules-to-prevent-unauthorized-modifications-to-the-applications-behavior",children:"Recommendations for Developers: Thorough testing of applications in a controlled environment is advised before deploying them in production to ensure stability and security. Additionally, developers are encouraged to implement locked update rules to prevent unauthorized modifications to the application's behavior."}),"\n",(0,i.jsx)(n.h3,{id:"storage",children:"Storage"}),"\n",(0,i.jsx)(n.p,{children:"Overview: Storage on client nodes involves maintaining the state and data required for the decentralized applications they support."}),"\n",(0,i.jsx)(n.p,{children:"Functionality:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Local Storage: Each node stores application data locally, contributing to the overall decentralized storage model of the network. This ensures that data is distributed across the network, enhancing privacy and resilience against central points of failure."}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"encryption",children:"Encryption:"}),"\n",(0,i.jsx)(n.p,{children:"Data stored on client nodes can be encrypted, providing an additional layer of security and privacy for user data."}),"\n",(0,i.jsx)(n.h3,{id:"identity-management",children:"Identity Management"}),"\n",(0,i.jsx)(n.p,{children:"Overview: Managing identities on the Calimero Network is fundamental for ensuring secure and private interactions between nodes and applications.\nFunctionality:"}),"\n",(0,i.jsx)(n.h3,{id:"authentication",children:"Authentication"}),"\n",(0,i.jsx)(n.p,{children:"Nodes implement mechanisms for authenticating users and applications, ensuring that interactions are secure and that entities are who they claim to be."}),"\n",(0,i.jsx)(n.h3,{id:"key-management",children:"Key Management"}),"\n",(0,i.jsx)(n.p,{children:"The management of cryptographic keys is an integral part of identity management, enabling secure communication and data encryption across the network."}),"\n",(0,i.jsx)(n.h3,{id:"application-marketplace",children:"Application Marketplace"}),"\n",(0,i.jsx)(n.p,{children:"Current State: The marketplace for decentralized applications within the Calimero Network is facilitated by a smart contract on the NEAR blockchain, with application data and metadata hosted on IPFS. This setup serves as a temporary solution while further community engagement and discussions are underway to refine the marketplace's infrastructure and governance.\nThe Calimero Network's approach to client nodes emphasizes security, decentralization, and privacy, with a strong recommendation for users to engage with applications that have securely locked update mechanisms. These applications are more reliable for critical use cases and are the only ones featured in the official marketplace, ensuring a curated and trustworthy selection of DApps for users. This framework demonstrates Calimero Network's commitment to building a secure and user-centric decentralized ecosystem."})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},5710:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>s});var i=t(758);const o={},a=i.createContext(o);function r(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/77c0519e.5d4c0744.js b/assets/js/77c0519e.5d4c0744.js new file mode 100644 index 00000000..086829d7 --- /dev/null +++ b/assets/js/77c0519e.5d4c0744.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[636],{6197:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var n=i(6070),o=i(5710);const a={id:"quickstart",title:"Quickstart"},r=void 0,s={id:"build/quickstart",title:"Quickstart",description:"Welcome to the exciting world of application development in the decentralized space! As a developer, you have the opportunity to build cutting-edge applications using our comprehensive suite of tools. Start by shaping the core application logic with our Protocol SDK and then bring your application to life by crafting intuitive user interfaces with the Client SDK. Join our community of developers and start creating powerful decentralized applications that can make a significant impact in the tech world.",source:"@site/docs/03-build/00-quickstart.mdx",sourceDirName:"03-build",slug:"/build/quickstart",permalink:"/build/quickstart",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedAt:1718189423e3,sidebarPosition:0,frontMatter:{id:"quickstart",title:"Quickstart"},sidebar:"tutorialSidebar",previous:{title:"Encryption",permalink:"/learn/advanced-concepts/encryption"},next:{title:"Protocol SDK",permalink:"/build/protocol-sdks/protocol-sdk"}},l={},c=[{value:"Protocol SDK",id:"protocol-sdk",level:2},{value:"Client SDKs",id:"client-sdks",level:2},{value:"Publish app",id:"publish-app",level:2}];function p(e){const t={a:"a",h2:"h2",li:"li",ol:"ol",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:"Welcome to the exciting world of application development in the decentralized space! As a developer, you have the opportunity to build cutting-edge applications using our comprehensive suite of tools. Start by shaping the core application logic with our Protocol SDK and then bring your application to life by crafting intuitive user interfaces with the Client SDK. Join our community of developers and start creating powerful decentralized applications that can make a significant impact in the tech world."}),"\n",(0,n.jsx)(t.p,{children:"Application development consists of two main parts:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsx)(t.li,{children:"building the application logic with the Protocol SDK"}),"\n",(0,n.jsx)(t.li,{children:"building the application client interface with the Client SDK"}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"protocol-sdk",children:"Protocol SDK"}),"\n",(0,n.jsx)(t.p,{children:"The Protocol SDK within the Calimero Network equips developers with tools for creating, testing, and deploying protocols essential for decentralized applications (DApps). It features capabilities such as code generation, security enhancement, and interoperability support to ensure robust and efficient DApp operations. This SDK is crucial for integrating with the Calimero Network's components, facilitating seamless updates and versioning critical for DApps in fields like decentralized messaging and finance."}),"\n",(0,n.jsx)(t.p,{children:"Currently we have SDK only for rust but in the future we will have SDKs for other languages as well."}),"\n",(0,n.jsx)(t.h2,{id:"client-sdks",children:"Client SDKs"}),"\n",(0,n.jsx)(t.p,{children:"The Client SDK includes straightforward tools to help you build your application. For logging in, we provide functions that allow users to authenticate using their wallet credentials, which must be set up as root keys in the admin dashboard. This setup ensures that access is both secure and straightforward. For handling data, the SDK supports JSON-RPC for direct data transactions and websockets for live updates. These features are designed to make your development process efficient and effective, allowing you to focus on creating a great user experience."}),"\n",(0,n.jsx)(t.p,{children:"Currently we have SDK only for typescript but in the future we will have SDKs for other languages as well."}),"\n",(0,n.jsx)(t.h2,{id:"publish-app",children:"Publish app"}),"\n",(0,n.jsxs)(t.p,{children:["After you have created your application logic with Rust and your application UI with TypeScript, you can publish your app. Follow instructions in the ",(0,n.jsx)(t.a,{href:"/build/publish-app",children:"Publish App"})," guide to learn how to publish your app and how users can download and run it."]})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},5710:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>s});var n=i(758);const o={},a=n.createContext(o);function r(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/799afb5f.98b299e2.js b/assets/js/799afb5f.98b299e2.js new file mode 100644 index 00000000..6e45b064 --- /dev/null +++ b/assets/js/799afb5f.98b299e2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[620],{6226:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var n=i(6070),o=i(5710);const r={id:"terminology",title:"Terminology"},s=void 0,a={id:"learn/terminology",title:"Terminology",description:"As projects grow, it's important to have a shared vocabulary to help communicate effectively. This page provides a list of terms used in the documentation and throughout the codebase.",source:"@site/docs/02-learn/02-terminology.mdx",sourceDirName:"02-learn",slug:"/learn/terminology",permalink:"/learn/terminology",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedAt:1718189423e3,sidebarPosition:2,frontMatter:{id:"terminology",title:"Terminology"},sidebar:"tutorialSidebar",previous:{title:"Architecture",permalink:"/learn/architecture"},next:{title:"Identity",permalink:"/learn/core-concepts/identity"}},c={},l=[];function d(e){const t={li:"li",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:"As projects grow, it's important to have a shared vocabulary to help communicate effectively. This page provides a list of terms used in the documentation and throughout the codebase."}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"Node"})," is any individual device or computer that participates in the network. To avoid confusion with network layer used in the protocol, instead of network we are using term ",(0,n.jsx)(t.strong,{children:"Context"}),"."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"Peer"})," is a specific instance of a node within a P2P network that interacts with other peers. Peer represents user."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"Peer Id"})," is a unique identifier assigned to each peer in the network. It is used to distinguish between different peers and ensure that messages are delivered to the correct recipient."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"Context"})," is the core of the Calimero ecosystem. It is an application specific network designed to enable direct communication between users, eliminating the need for intermediaries"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"Application"})," is a software program designed to perform specific tasks or solve particular problems. To ensure compatibility and functionality, it should be developed according to the protocol SDK instructions provided. Once developed, the application should be published in a format that others can use during runtime, specifically in WebAssembly (WASM) format. Developer can also build frontend for an application, deployed separately, allowing users to interact with an app directly. This user interface facilitates interaction with the underlying software, making the application accessible and user-friendly."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"Root key"})," is the public part of a wallet cryptographic key pair used to verify the signature of sensitive actions. This public key is used to ensure that any data or actions signed with the corresponding private key can be trusted. Essentially, the root key serves as a trust anchor, enabling users to validate the authenticity and integrity of operations or communications associated with the node. It does not grant direct control over the node but ensures that actions authenticated with the private part of the root key are legitimate."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"Client key"})," is a cryptographic key tailored for each user session, acting as a session key or token. Each client key must be signed with the root key to be valid which is done automatically during login. This ensures that only sessions authenticated by the trusted root key can interact with the node."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"Specialized node"})," is third-party node that augment a context's capacity and reliability. It participates in a context but have additional capabilities, providing various services while maintaining the decentralized nature of the network."]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},5710:(e,t,i)=>{i.d(t,{R:()=>s,x:()=>a});var n=i(758);const o={},r=n.createContext(o);function s(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/90e69b51.9508d61e.js b/assets/js/90e69b51.9508d61e.js new file mode 100644 index 00000000..ea7686d0 --- /dev/null +++ b/assets/js/90e69b51.9508d61e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[262],{3564:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>h,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var o=n(6070),a=n(5710);const i={id:"hackathons",title:"Hackathons"},r="Hackathons",s={id:"contribute/hackathons",title:"Hackathons",description:"At Calimero, we love innovation and collaboration, which is why we plan to regularly organize hackathons that include our product. We have exciting events planned for the future. Stay tuned by following us on our social media channels to get the latest updates.",source:"@site/docs/04-contribute/02-hackathons.mdx",sourceDirName:"04-contribute",slug:"/contribute/hackathons",permalink:"/contribute/hackathons",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedAt:1718189423e3,sidebarPosition:2,frontMatter:{id:"hackathons",title:"Hackathons"},sidebar:"tutorialSidebar",previous:{title:"Github",permalink:"/contribute/github"},next:{title:"Bounty Program",permalink:"/contribute/bounty-program"}},h={},l=[{value:"What is a Hackathon?",id:"what-is-a-hackathon",level:2},{value:"How to Get Involved",id:"how-to-get-involved",level:2},{value:"Stay Updated",id:"stay-updated",level:3}];function c(e){const t={h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"hackathons",children:"Hackathons"}),"\n",(0,o.jsx)(t.p,{children:"At Calimero, we love innovation and collaboration, which is why we plan to regularly organize hackathons that include our product. We have exciting events planned for the future. Stay tuned by following us on our social media channels to get the latest updates."}),"\n",(0,o.jsx)(t.h2,{id:"what-is-a-hackathon",children:"What is a Hackathon?"}),"\n",(0,o.jsx)(t.p,{children:"A hackathon is an event where developers, designers, and other tech enthusiasts come together to create innovative solutions in a short amount of time. Participants work in teams to build projects, often centered around a specific theme or technology. Hackathons are a great opportunity to:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Learn New Skills:"})," Whether you\u2019re a beginner or an expert, hackathons provide a platform to learn new technologies and tools."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Collaborate:"})," Work with other passionate individuals, share ideas, and collaborate on projects."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Showcase Your Talent:"})," Present your project to a panel of judges and other participants, winning prizes and recognition."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Network:"})," Meet like-minded individuals, industry experts, and potential employers or collaborators."]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"how-to-get-involved",children:"How to Get Involved"}),"\n",(0,o.jsx)(t.p,{children:"When we announce a new hackathon, here\u2019s how you can participate:"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Register for the Event:"})," Sign up through the event link provided in our announcements."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Form a Team:"})," Join with friends or team up with other participants."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Build Your Project:"})," Use our product and other tools to create something amazing."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Submit Your Work:"})," Present your project at the end of the hackathon for a chance to win prizes and gain recognition."]}),"\n"]}),"\n",(0,o.jsx)(t.h3,{id:"stay-updated",children:"Stay Updated"}),"\n",(0,o.jsx)(t.p,{children:"Follow us on social media to be the first to know about our upcoming hackathons and other events. We\u2019ll share all the details, including how to register and participate."}),"\n",(0,o.jsx)(t.p,{children:"Thank you for your interest in contributing to our project through hackathons. We look forward to seeing your innovative ideas and solutions!"})]})}function d(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},5710:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>s});var o=n(758);const a={},i=o.createContext(a);function r(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/910b5ce4.a516eb9e.js b/assets/js/910b5ce4.a516eb9e.js new file mode 100644 index 00000000..dd0e2ccc --- /dev/null +++ b/assets/js/910b5ce4.a516eb9e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[968],{9625:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var o=n(6070),a=n(5710);const r={id:"example-app",title:"Example Application"},i=void 0,l={id:"explore/developers-quickstart/example-app",title:"Example Application",description:"We have created simple and easy to use example application called only-peers. Application enables writing posts and leaving comments.",source:"@site/docs/01-explore/04-developers-quickstart/03-example-app.mdx",sourceDirName:"01-explore/04-developers-quickstart",slug:"/explore/developers-quickstart/example-app",permalink:"/explore/developers-quickstart/example-app",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedAt:1718189423e3,sidebarPosition:3,frontMatter:{id:"example-app",title:"Example Application"},sidebar:"tutorialSidebar",previous:{title:"Admin Dashboard",permalink:"/explore/developers-quickstart/admin-dashboard"},next:{title:"Architecture",permalink:"/learn/architecture"}},s={},p=[{value:"Create new context",id:"create-new-context",level:3},{value:"Try out Only-peers application",id:"try-out-only-peers-application",level:3}];function c(e){const t={a:"a",blockquote:"blockquote",code:"code",em:"em",h3:"h3",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(t.p,{children:["We have created simple and easy to use example application called ",(0,o.jsx)(t.code,{children:"only-peers"}),". Application enables writing posts and leaving comments.\nTo try out application you need to create new context where application will be installed."]}),"\n",(0,o.jsx)(t.h3,{id:"create-new-context",children:"Create new context"}),"\n",(0,o.jsxs)(t.p,{children:["Navigate back to Admin Dashboard. If you have not started Admin Dashboard, follow the instructions in ",(0,o.jsx)(t.a,{href:"/explore/developers-quickstart/admin-dashboard",children:"Admin Dashboard"}),"."]}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["Follow context creation instructions and select ",(0,o.jsx)(t.code,{children:"only-peers"})," app."]}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"You are now part of the context and can start using the application."}),"\n",(0,o.jsx)(t.h3,{id:"try-out-only-peers-application",children:"Try out Only-peers application"}),"\n",(0,o.jsx)(t.p,{children:"We have built and deployed a demo app so you can try it out immediately."}),"\n",(0,o.jsxs)(t.p,{children:["Navigate to ",(0,o.jsx)(t.a,{href:"https://calimero-network.github.io/only-peers-client/",children:"https://calimero-network.github.io/only-peers-client/"})," to access app frontend."]}),"\n",(0,o.jsxs)(t.p,{children:["You will be asked to setup the app by the adding the node url. It is the same url you used while starting the node in ",(0,o.jsx)(t.a,{href:"/explore/developers-quickstart/getting-started",children:"Getting-started"})," ",(0,o.jsx)(t.code,{children:"http://localhost:NODE_PORT"}),"\nAfter setting up node url, you will be asked to login."]}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.strong,{children:(0,o.jsx)(t.em,{children:"NOTE:"})}),"\nUse your wallet which you have already added as root key in ",(0,o.jsx)(t.a,{href:"/explore/developers-quickstart/admin-dashboard",children:"Admin Dashboard. "})]}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"You are now ready to use the app. Enjoy!"})]})}function d(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},5710:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>l});var o=n(758);const a={},r=o.createContext(a);function i(e){const t=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),o.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9471ce52.efa3a852.js b/assets/js/9471ce52.efa3a852.js new file mode 100644 index 00000000..19a7a5f6 --- /dev/null +++ b/assets/js/9471ce52.efa3a852.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[229],{4007:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>p,frontMatter:()=>a,metadata:()=>r,toc:()=>c});var t=i(6070),s=i(5710);const a={id:"applications",title:"Applications"},o=void 0,r={id:"learn/core-concepts/applications",title:"Applications",description:"Applications in Calimero define the core logic governing how peers interact within a decentralized network. Developers can programmatically augment the protocol to create customized functionalities, supporting a wide range of applications tailored to various use cases, from direct messaging and communication channels to interactive games and collaborative editing.",source:"@site/docs/02-learn/03-core-concepts/03-applications.mdx",sourceDirName:"02-learn/03-core-concepts",slug:"/learn/core-concepts/applications",permalink:"/learn/core-concepts/applications",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedAt:1718189423e3,sidebarPosition:3,frontMatter:{id:"applications",title:"Applications"},sidebar:"tutorialSidebar",previous:{title:"Admin Client API",permalink:"/learn/core-concepts/node/admin-client-api"},next:{title:"Contexts",permalink:"/learn/core-concepts/contexts"}},l={},c=[{value:"Examples of Applications",id:"examples-of-applications",level:3},{value:"Benefits of Decentralized Applications",id:"benefits-of-decentralized-applications",level:3},{value:"Security and Data Management",id:"security-and-data-management",level:3},{value:"Building Applications",id:"building-applications",level:3}];function d(e){const n={h3:"h3",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"Applications in Calimero define the core logic governing how peers interact within a decentralized network. Developers can programmatically augment the protocol to create customized functionalities, supporting a wide range of applications tailored to various use cases, from direct messaging and communication channels to interactive games and collaborative editing."}),"\n",(0,t.jsx)(n.h3,{id:"examples-of-applications",children:"Examples of Applications"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Communication Platforms"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Direct Messages and Channels"}),": Support for private, encrypted messaging between users and group communications in shared, secure spaces. This setup can scale from one-on-one conversations to large group discussions, similar to Slack channels or Discord communities."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Community Platforms"}),": Decentralized alternatives to platforms like Reddit or Hacker News, enabling independent contexts for different purposes, fostering discussions, and sharing content securely."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Interactive Games"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Privacy-Focused Games"}),": These games require the privacy of each player's moves until both have played, ensuring fair play and maintaining the confidentiality of strategies. Examples include:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Rock-Paper-Scissors"}),": Players' choices are revealed simultaneously after both have made their moves."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Battleship"}),": The positions of ships are kept secret until revealed through gameplay."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Non-Privacy Games"}),": These games do not require concealment of moves and allow all actions to be visible to both players. Examples include:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Chess"}),": A strategy game where all moves are visible to both players, with game logic running locally."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Checkers"}),": Another strategy game where all moves are open and visible to both players."]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Collaborative Work"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Document Collaboration"}),": Real-time collaboration on documents, akin to Google Docs, but decentralized and secure."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Creative Projects"}),": Shared canvases or environments for drawing, designing, or working on various creative projects, where all contributions are securely encrypted."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"benefits-of-decentralized-applications",children:"Benefits of Decentralized Applications"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Resilience"}),": Distributed application logic ensures the system functions smoothly even if some devices go offline."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Autonomy"}),": Users control their data and activities without relying on a central authority."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Scalability"}),": The system scales effectively as more users join due to optimistic execution, with state being conflict-free and eventually reconciled."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Privacy"}),": Keeping data local and encrypted prevents exposure to third parties, crucial for sensitive information."]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"security-and-data-management",children:"Security and Data Management"}),"\n",(0,t.jsx)(n.p,{children:"All non-state-transitional data, such as attached files in DMs, collaborative document assets, and game resources, inherit the same level of security as state-transitional transactions. This ensures that all forms of data within the Calimero network are encrypted and secure."}),"\n",(0,t.jsx)(n.p,{children:"Calimero also functions as a decentralized filesystem for these non-state-transitional, encrypted blobs of data. Similar to BitTorrent or IPFS, nodes can lazily share the data without needing any centralized storage options. This decentralized approach allows for efficient and secure data distribution across the network."}),"\n",(0,t.jsx)(n.h3,{id:"building-applications",children:"Building Applications"}),"\n",(0,t.jsx)(n.p,{children:"Developers can leverage Calimero's framework to programmatically build and augment a wide range of applications using provided tools and documentation. This includes setting up the development environment and deploying applications within the network."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Development Tools"}),"\nCalimero offers the Rust SDK and intuitive APIs, enabling developers to create applications that integrate seamlessly with the network."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Documentation and Support"}),"\nComprehensive documentation and community support assist developers in every step of the application development process, ensuring that they can build and deploy high-quality, secure applications efficiently."]}),"\n"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},5710:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>r});var t=i(758);const s={},a=t.createContext(s);function o(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/962e3ea7.0848e97b.js b/assets/js/962e3ea7.0848e97b.js new file mode 100644 index 00000000..7408ecc8 --- /dev/null +++ b/assets/js/962e3ea7.0848e97b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[77],{334:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>t,metadata:()=>l,toc:()=>c});var i=s(6070),r=s(5710);const t={id:"network",title:"Network"},o=void 0,l={id:"learn/core-concepts/node/network",title:"Network",description:"Overview",source:"@site/docs/02-learn/03-core-concepts/02-node/05-network.mdx",sourceDirName:"02-learn/03-core-concepts/02-node",slug:"/learn/core-concepts/node/network",permalink:"/learn/core-concepts/node/network",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedAt:1718189423e3,sidebarPosition:5,frontMatter:{id:"network",title:"Network"},sidebar:"tutorialSidebar",previous:{title:"Storage",permalink:"/learn/core-concepts/node/storage"},next:{title:"Admin Client API",permalink:"/learn/core-concepts/node/admin-client-api"}},a={},c=[{value:"Overview",id:"overview",level:2},{value:"Node Types",id:"node-types",level:2},{value:"Client Node",id:"client-node",level:3},{value:"Boot Node",id:"boot-node",level:3},{value:"P2P protocols and techniques",id:"p2p-protocols-and-techniques",level:2},{value:"Protocol Descriptions",id:"protocol-descriptions",level:3},{value:"DCUtR (Direct Connection Upgrade through Relay)",id:"dcutr-direct-connection-upgrade-through-relay",level:4},{value:"Gossipsub",id:"gossipsub",level:4},{value:"Identify",id:"identify",level:4},{value:"Kademlia (Kad)",id:"kademlia-kad",level:4},{value:"mDNS (Multicast DNS)",id:"mdns-multicast-dns",level:4},{value:"Ping",id:"ping",level:4},{value:"Relay",id:"relay",level:4},{value:"Rendezvous",id:"rendezvous",level:4},{value:"NAT Traversal Techniques",id:"nat-traversal-techniques",level:3}];function d(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsxs)(n.p,{children:["This document provides an overview of the networking component of Calimero Network, which is implemented using the ",(0,i.jsx)(n.code,{children:"libp2p"})," library. The network consists of two types of peers: client nodes and boot nodes, each serving distinct roles and utilizing specific protocols to facilitate peer-to-peer communication.\nClient node is the component which hosts and runs client applications, communicates and shares data between other client nodes.\nBoot node is the component used for the initial discovery of the peers in the network."]}),"\n",(0,i.jsx)(n.h2,{id:"node-types",children:"Node Types"}),"\n",(0,i.jsx)(n.h3,{id:"client-node",children:"Client Node"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Deployment:"})," Can run on any machine"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Protocols Utilized:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#dcutr-direct-connection-upgrade-through-relay",children:"dcutr"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#gossipsub",children:"gossipsub"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#identify",children:"identify"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#kademlia-kad",children:"kad"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#mdns-multicast-dns",children:"mdns"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#ping",children:"ping"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#rendezvous",children:"rendezvous"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#relay",children:"relay"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Behavior:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Configuration:"})," A client node can be configured to use zero boot nodes."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"External Address:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Direct Public External Address:"})," Nodes with a direct public external address do not require reservation at the relay server. These nodes publish their public external address to the Kademlia DHT, making them directly accessible to other peers."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Relayed External Address:"})," Nodes that do not have a direct public external address, typically those behind a NAT or firewall, can obtain a relayed external address by requesting a reservation at a relay server. Once the reservation is accepted, the node publishes its new external address to the rendezvous server. This allows other nodes to discover relayed addresses of a peers in a certain rendezvous namespace. The relay server can be used for the coordination of the hole punching between two nodes. If the hole punching attempt fails, the relay server will bridge the traffic."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Discovery Protocols:"})," ",(0,i.jsx)(n.code,{children:"mDNS"}),", ",(0,i.jsx)(n.code,{children:"rendezvous"})," and ",(0,i.jsx)(n.code,{children:"Kademlia"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Connection Management:"})," A peer, identified via PeerId, can be discovered either via mDNS, rendezvous or Kademlia. mDNS discovery provides local network addresses, rendezvous discovery provides relayed addresses, and Kademlia discovery provides direct public external addresses. The node maintains information about its connections to peers, including the discovery source. For a discovered external address, either relayed or direct public, the node will only attempt to dial the peer if the same peer is not already connected via a discovered local address. This ensures that local connections have higher priority and that there are no unnecessary hole punching attempts."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Message Relaying:"})," The node participates in the ",(0,i.jsx)(n.code,{children:"gossipsub"})," protocol, relaying messages to all connected peers that support it. This enables efficient and scalable message dissemination across the network."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"boot-node",children:"Boot Node"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Deployment:"})," Must run on a publicly available machine with a static IP address."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Protocols Utilized:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#identify",children:"identify"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#kademlia-kad",children:"kad"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#ping",children:"ping"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#rendezvous",children:"rendezvous"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#relay",children:"relay"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Behavior:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Characteristics:"})," Boot nodes are publicly available, long-running nodes that provide stable entry points to the network."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Functions:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Bootstrap Node:"})," Acts as a well-known peer for the Kademlia protocol, facilitating peer discovery and network join operations."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Circuit Relay Server:"})," Serves as a generic relay that provides the medium that facilitates the hole punching, enabling peers to establish direct connections even when they are behind NAT or firewalls. The relay server is used for the coordination of the hole punching between two nodes, and briding traffic if the hole punching attempt fails."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Rendezvous Server:"})," Facilitates peer discovery by allowing nodes to register their presence and query for other peers within a shared rendezvous namespace. This enables dynamic and efficient peer-to-peer connections without relying on a static list of peers."]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"p2p-protocols-and-techniques",children:"P2P protocols and techniques"}),"\n",(0,i.jsx)(n.h3,{id:"protocol-descriptions",children:"Protocol Descriptions"}),"\n",(0,i.jsx)(n.h4,{id:"dcutr-direct-connection-upgrade-through-relay",children:"DCUtR (Direct Connection Upgrade through Relay)"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"DCUtR is used to upgrade connections through relay nodes, allowing peers to establish direct connections even if they are behind NATs or firewalls. Peers initially connect via a relay node, then use the DCUtR protocol to attempt a direct connection, which reduces latency and bandwidth usage."}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Reference:"})," ",(0,i.jsx)(n.a,{href:"https://github.com/libp2p/specs/blob/master/relay/DCUtR.md",children:"libp2p DCUtR Documentation"})]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"gossipsub",children:"Gossipsub"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Gossipsub is a scalable and efficient pub-sub protocol for message dissemination. It combines the best aspects of gossip protocols and topic-based pub-sub systems. It minimizes bandwidth usage by only gossiping metadata and ensuring that messages are only sent once per peer."}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Reference:"})," ",(0,i.jsx)(n.a,{href:"https://github.com/libp2p/specs/tree/master/pubsub/gossipsub",children:"libp2p Gossipsub Documentation"})]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"identify",children:"Identify"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The Identify protocol allows peers to identify themselves and share their capabilities with other peers. Peers exchange identification information such as supported protocols, listen addresses, and public keys. This helps peers make informed decisions about connecting and interacting."}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Reference:"})," ",(0,i.jsx)(n.a,{href:"https://github.com/libp2p/specs/blob/master/identify/README.md",children:"libp2p Identify Documentation"})]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"kademlia-kad",children:"Kademlia (Kad)"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Kademlia is a distributed hash table (DHT) protocol used for peer discovery and data routing. It uses an XOR metric to ensure efficient and scalable peer lookup. Each node maintains a routing table with information about other nodes, facilitating quick lookups and robust network operation."}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Reference:"})," ",(0,i.jsx)(n.a,{href:"https://github.com/libp2p/specs/tree/master/kad-dht",children:"libp2p Kademlia DHT Documentation"})]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"mdns-multicast-dns",children:"mDNS (Multicast DNS)"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"mDNS enables local network peer discovery without the need for a central server. It uses multicast DNS to allow peers to find each other on the same local network by broadcasting their presence and listening for broadcasts from other peers."}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Reference:"})," ",(0,i.jsx)(n.a,{href:"https://github.com/libp2p/specs/tree/master/discovery/mdns",children:"libp2p mDNS Documentation"})]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"ping",children:"Ping"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The Ping protocol measures the round-trip time (latency) between peers. It regularly pings connected peers and measures the time it takes for a response. This helps in maintaining healthy connections and understanding network latency."}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Reference:"})," ",(0,i.jsx)(n.a,{href:"https://github.com/libp2p/go-libp2p-ping",children:"libp2p Ping Documentation"})]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"relay",children:"Relay"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The Relay protocol supports relay-based communication, allowing peers to communicate through intermediary nodes when direct connections are not possible. Nodes can use relay nodes to forward their traffic, which is especially useful for nodes behind NATs or firewalls. The protocol includes mechanisms for reserving relay slots and managing relay connections."}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Reference:"})," ",(0,i.jsx)(n.a,{href:"https://github.com/libp2p/specs/tree/master/relay",children:"libp2p Relay Documentation"})]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"rendezvous",children:"Rendezvous"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The Rendezvous protocol enables peers to discover each other by registering at and querying a shared rendezvous point. This is useful for dynamically finding peers without needing a central directory or pre-established list of peers. Peers register their presence at a rendezvous server and can also query the server to find other peers."}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Reference:"})," ",(0,i.jsx)(n.a,{href:"https://github.com/libp2p/specs/tree/master/rendezvous",children:"libp2p Rendezvous Documentation"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"nat-traversal-techniques",children:"NAT Traversal Techniques"}),"\n",(0,i.jsxs)(n.p,{children:["One of the common techniques used for NAT traversal in P2P networks is ",(0,i.jsx)(n.strong,{children:"Hole Punching"}),". This technique allows two peers, each behind a NAT, to establish a direct connection with each other. Here's a brief explanation:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Hole Punching:"})," This technique involves three steps:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Step 1 - Connection to Public Server:"}),' Both peers initially connect to a public server (in this case, the relay server). This creates a NAT mapping (a "hole") for outgoing packets to the server.']}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Step 2 - Exchange of Address Information:"})," The server shares the public address information of each peer with the other. This information includes the IP address and port number that the NAT has assigned for the connection to the server."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Step 3 - Direct Connection:"})," Each peer sends a packet to the other peer's public address. Since a mapping for this address already exists in the NAT (from the connection to the server), the NAT forwards the packet to the appropriate internal address, and a direct connection is established."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"This technique is particularly useful in P2P networks, as it allows peers to communicate directly, reducing the load on relay servers and improving network efficiency. However, it's worth noting that hole punching may not work with all types of NATs, and success can depend on the specific NAT implementation and configuration."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Reference:"})," ",(0,i.jsx)(n.a,{href:"https://blog.ipfs.tech/2022-01-20-libp2p-hole-punching/",children:"Hole punching in libp2p"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Reference:"})," ",(0,i.jsx)(n.a,{href:"https://tailscale.com/blog/how-nat-traversal-works",children:"How NAT traversal works"})]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},5710:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>l});var i=s(758);const r={},t=i.createContext(r);function o(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/964ce0ca.2a2af6f0.js b/assets/js/964ce0ca.2a2af6f0.js new file mode 100644 index 00000000..f41c0686 --- /dev/null +++ b/assets/js/964ce0ca.2a2af6f0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[106],{4552:(e,i,t)=>{t.r(i),t.d(i,{assets:()=>o,contentTitle:()=>s,default:()=>u,frontMatter:()=>p,metadata:()=>l,toc:()=>r});var n=t(6070),a=t(5710);const p={id:"publish-app",title:"Publish App"},s=void 0,l={id:"build/publish-app",title:"Publish App",description:"After you have built your application, you can publish it to the network. This will make it available for users to interact with.",source:"@site/docs/03-build/03-publish-app.mdx",sourceDirName:"03-build",slug:"/build/publish-app",permalink:"/build/publish-app",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedAt:1718189423e3,sidebarPosition:3,frontMatter:{id:"publish-app",title:"Publish App"},sidebar:"tutorialSidebar",previous:{title:"TypeScript Client SDK",permalink:"/build/client-sdks/client-ts-sdk"},next:{title:"Github",permalink:"/contribute/github"}},o={},r=[{value:"Publishing application",id:"publishing-application",level:2},{value:"Application preview",id:"application-preview",level:2},{value:"Example app preview",id:"example-app-preview",level:2}];function c(e){const i={a:"a",code:"code",h2:"h2",img:"img",p:"p",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(i.p,{children:"After you have built your application, you can publish it to the network. This will make it available for users to interact with."}),"\n",(0,n.jsx)(i.h2,{id:"publishing-application",children:"Publishing application"}),"\n",(0,n.jsxs)(i.p,{children:["Navigate to ",(0,n.jsx)(i.a,{href:"../explore/developers-quickstart/admin-dashboard",children:"Admin Dashboard"})," and select ",(0,n.jsx)(i.code,{children:"Applications"})," tab."]}),"\n",(0,n.jsx)(i.p,{children:(0,n.jsx)(i.img,{alt:"Publish application",src:t(8617).A+"",width:"1968",height:"1562"})}),"\n",(0,n.jsx)(i.p,{children:"Enter the required data and publish the application. After publishing, your application will be available for users to interact with in new contexts."}),"\n",(0,n.jsx)(i.h2,{id:"application-preview",children:"Application preview"}),"\n",(0,n.jsx)(i.p,{children:"Good practice allows users to try an app before they decide to use it. You can deploy an app to any host provider."}),"\n",(0,n.jsxs)(i.p,{children:["We have used Github Pages to preview our ",(0,n.jsx)(i.a,{href:"../explore/developers-quickstart/example-app",children:"example app"}),". You can do the same by following the steps below."]}),"\n",(0,n.jsx)(i.h2,{id:"example-app-preview",children:"Example app preview"}),"\n",(0,n.jsxs)(i.p,{children:["First you need to enable Github Pages by following ",(0,n.jsx)(i.a,{href:"https://docs.github.com/en/pages/getting-started-with-github-pages/creating-a-github-pages-site",children:"Creating a Github Pages"})]}),"\n",(0,n.jsxs)(i.p,{children:["Our example app is written in next.js and code is available in ",(0,n.jsx)(i.a,{href:"https://github.com/calimero-network/only-peers-client",children:"only-peers-client"}),"\nAfter enabling Github Pages, a few changes are required in your next.js app.\n",(0,n.jsx)(i.code,{children:"next.config.mjs"}),' should contain output: "export" field']}),"\n",(0,n.jsxs)(i.p,{children:["Github Actions is a platform used to automate the deployment process. You can find example in ",(0,n.jsx)(i.a,{href:"https://github.com/calimero-network/only-peers-client/tree/master/.github/workflows",children:"github workflow"})]})]})}function u(e={}){const{wrapper:i}={...(0,a.R)(),...e.components};return i?(0,n.jsx)(i,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},8617:(e,i,t)=>{t.d(i,{A:()=>n});const n=t.p+"assets/images/publish-new-application-f4493f9baa5b1dc59d62ab483b52bb65.png"},5710:(e,i,t)=>{t.d(i,{R:()=>s,x:()=>l});var n=t(758);const a={},p=n.createContext(a);function s(e){const i=n.useContext(p);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function l(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),n.createElement(p.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a7456010.d714be23.js b/assets/js/a7456010.d714be23.js new file mode 100644 index 00000000..f6be58ac --- /dev/null +++ b/assets/js/a7456010.d714be23.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[616],{8552:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-pages","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/a7bd4aaa.9b88e1ff.js b/assets/js/a7bd4aaa.9b88e1ff.js new file mode 100644 index 00000000..d6112068 --- /dev/null +++ b/assets/js/a7bd4aaa.9b88e1ff.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[98],{6829:(n,e,s)=>{s.r(e),s.d(e,{default:()=>d});s(758);var r=s(3896),o=s(5266),t=s(8051),c=s(1977),i=s(2622),u=s(6070);function a(n){const{version:e}=n;return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(i.A,{version:e.version,tag:(0,o.tU)(e.pluginId,e.version)}),(0,u.jsx)(r.be,{children:e.noIndex&&(0,u.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})]})}function l(n){const{version:e,route:s}=n;return(0,u.jsx)(r.e3,{className:e.className,children:(0,u.jsx)(t.n,{version:e,children:(0,c.v)(s.routes)})})}function d(n){return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(a,{...n}),(0,u.jsx)(l,{...n})]})}}}]); \ No newline at end of file diff --git a/assets/js/a94703ab.0743a859.js b/assets/js/a94703ab.0743a859.js new file mode 100644 index 00000000..8e667c0a --- /dev/null +++ b/assets/js/a94703ab.0743a859.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[48],{8034:(e,t,n)=>{n.r(t),n.d(t,{default:()=>be});var a=n(758),o=n(3526),i=n(3896),s=n(2702),l=n(3766),r=n(2987),c=n(7706),d=n(3709),u=n(3403);const m={backToTopButton:"backToTopButton_SKCq",backToTopButtonShow:"backToTopButtonShow_bF2A"};var b=n(6070);function h(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,o]=(0,a.useState)(!1),i=(0,a.useRef)(!1),{startScroll:s,cancelScroll:l}=(0,d.gk)();return(0,d.Mq)(((e,n)=>{let{scrollY:a}=e;const s=n?.scrollY;s&&(i.current?i.current=!1:a>=s?(l(),o(!1)):a {e.location.hash&&(i.current=!0,o(!1))})),{shown:n,scrollToTop:()=>s(0)}}({threshold:300});return(0,b.jsx)("button",{"aria-label":(0,c.T)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,o.A)("clean-btn",s.G.common.backToTopButton,m.backToTopButton,e&&m.backToTopButtonShow),type:"button",onClick:t})}var p=n(2838),x=n(5557),f=n(3104),j=n(8949),v=n(1240);function _(e){return(0,b.jsx)("svg",{width:"20",height:"20","aria-hidden":"true",...e,children:(0,b.jsxs)("g",{fill:"#7a7a7a",children:[(0,b.jsx)("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),(0,b.jsx)("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})]})})}const g={collapseSidebarButton:"collapseSidebarButton_JXXE",collapseSidebarButtonIcon:"collapseSidebarButtonIcon_IFmu"};function A(e){let{onClick:t}=e;return(0,b.jsx)("button",{type:"button",title:(0,c.T)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,o.A)("button button--secondary button--outline",g.collapseSidebarButton),onClick:t,children:(0,b.jsx)(_,{className:g.collapseSidebarButtonIcon})})}var C=n(42),S=n(1495);const k=Symbol("EmptyContext"),T=a.createContext(k);function I(e){let{children:t}=e;const[n,o]=(0,a.useState)(null),i=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:o})),[n]);return(0,b.jsx)(T.Provider,{value:i,children:t})}var N=n(1661),B=n(428),y=n(8257),w=n(4272);function E(e){let{collapsed:t,categoryLabel:n,onClick:a}=e;return(0,b.jsx)("button",{"aria-label":t?(0,c.T)({id:"theme.DocSidebarItem.expandCategoryAriaLabel",message:"Expand sidebar category '{label}'",description:"The ARIA label to expand the sidebar category"},{label:n}):(0,c.T)({id:"theme.DocSidebarItem.collapseCategoryAriaLabel",message:"Collapse sidebar category '{label}'",description:"The ARIA label to collapse the sidebar category"},{label:n}),"aria-expanded":!t,type:"button",className:"clean-btn menu__caret",onClick:a})}function L(e){let{item:t,onItemClick:n,activePath:i,level:r,index:c,...d}=e;const{items:u,label:m,collapsible:h,className:p,href:x}=t,{docs:{sidebar:{autoCollapseCategories:f}}}=(0,j.p)(),v=function(e){const t=(0,w.A)();return(0,a.useMemo)((()=>e.href&&!e.linkUnlisted?e.href:!t&&e.collapsible?(0,l.Nr)(e):void 0),[e,t])}(t),_=(0,l.w8)(t,i),g=(0,B.ys)(x,i),{collapsed:A,setCollapsed:C}=(0,N.u)({initialState:()=>!!h&&(!_&&t.collapsed)}),{expandedItem:I,setExpandedItem:L}=function(){const e=(0,a.useContext)(T);if(e===k)throw new S.dV("DocSidebarItemsExpandedStateProvider");return e}(),H=function(e){void 0===e&&(e=!A),L(e?null:c),C(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:o}=e;const i=(0,S.ZC)(t);(0,a.useEffect)((()=>{t&&!i&&n&&o(!1)}),[t,i,n,o])}({isActive:_,collapsed:A,updateCollapsed:H}),(0,a.useEffect)((()=>{h&&null!=I&&I!==c&&f&&C(!0)}),[h,I,c,C,f]),(0,b.jsxs)("li",{className:(0,o.A)(s.G.docs.docSidebarItemCategory,s.G.docs.docSidebarItemCategoryLevel(r),"menu__list-item",{"menu__list-item--collapsed":A},p),children:[(0,b.jsxs)("div",{className:(0,o.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":g}),children:[(0,b.jsx)(y.A,{className:(0,o.A)("menu__link",{"menu__link--sublist":h,"menu__link--sublist-caret":!x&&h,"menu__link--active":_}),onClick:h?e=>{n?.(t),x?H(!1):(e.preventDefault(),H())}:()=>{n?.(t)},"aria-current":g?"page":void 0,role:h&&!x?"button":void 0,"aria-expanded":h&&!x?!A:void 0,href:h?v??"#":v,...d,children:m}),x&&h&&(0,b.jsx)(E,{collapsed:A,categoryLabel:m,onClick:e=>{e.preventDefault(),H()}})]}),(0,b.jsx)(N.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:A,children:(0,b.jsx)(z,{items:u,tabIndex:A?-1:0,onItemClick:n,activePath:i,level:r+1})})]})}var H=n(8167),M=n(7615);const W={menuExternalLink:"menuExternalLink_T2Zs"};function G(e){let{item:t,onItemClick:n,activePath:a,level:i,index:r,...c}=e;const{href:d,label:u,className:m,autoAddBaseUrl:h}=t,p=(0,l.w8)(t,a),x=(0,H.A)(d);return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(i),"menu__list-item",m),children:(0,b.jsxs)(y.A,{className:(0,o.A)("menu__link",!x&&W.menuExternalLink,{"menu__link--active":p}),autoAddBaseUrl:h,"aria-current":p?"page":void 0,to:d,...x&&{onClick:n?()=>n(t):void 0},...c,children:[u,!x&&(0,b.jsx)(M.A,{})]})},u)}const P={menuHtmlItem:"menuHtmlItem_KBjg"};function R(e){let{item:t,level:n,index:a}=e;const{value:i,defaultStyle:l,className:r}=t;return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(n),l&&[P.menuHtmlItem,"menu__list-item"],r),dangerouslySetInnerHTML:{__html:i}},a)}function D(e){let{item:t,...n}=e;switch(t.type){case"category":return(0,b.jsx)(L,{item:t,...n});case"html":return(0,b.jsx)(R,{item:t,...n});default:return(0,b.jsx)(G,{item:t,...n})}}function F(e){let{items:t,...n}=e;const a=(0,l.Y)(t,n.activePath);return(0,b.jsx)(I,{children:a.map(((e,t)=>(0,b.jsx)(D,{item:e,index:t,...n},t)))})}const z=(0,a.memo)(F),U={menu:"menu_vdXT",menuWithAnnouncementBar:"menuWithAnnouncementBar_jacn"};function V(e){let{path:t,sidebar:n,className:i}=e;const l=function(){const{isActive:e}=(0,C.M)(),[t,n]=(0,a.useState)(e);return(0,d.Mq)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return(0,b.jsx)("nav",{"aria-label":(0,c.T)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,o.A)("menu thin-scrollbar",U.menu,l&&U.menuWithAnnouncementBar,i),children:(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(z,{items:n,activePath:t,level:1})})})}const X="sidebar_BlfT",Y="sidebarWithHideableNavbar_HSHF",q="sidebarHidden_I1u8",Z="sidebarLogo_QiBE";function K(e){let{path:t,sidebar:n,onCollapse:a,isHidden:i}=e;const{navbar:{hideOnScroll:s},docs:{sidebar:{hideable:l}}}=(0,j.p)();return(0,b.jsxs)("div",{className:(0,o.A)(X,s&&Y,i&&q),children:[s&&(0,b.jsx)(v.A,{tabIndex:-1,className:Z}),(0,b.jsx)(V,{path:t,sidebar:n}),l&&(0,b.jsx)(A,{onClick:a})]})}const J=a.memo(K);var O=n(6083),Q=n(2483);const $=e=>{let{sidebar:t,path:n}=e;const a=(0,Q.M)();return(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(z,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&a.toggle(),"link"===e.type&&a.toggle()},level:1})})};function ee(e){return(0,b.jsx)(O.GX,{component:$,props:e})}const te=a.memo(ee);function ne(e){const t=(0,f.l)(),n="desktop"===t||"ssr"===t,a="mobile"===t;return(0,b.jsxs)(b.Fragment,{children:[n&&(0,b.jsx)(J,{...e}),a&&(0,b.jsx)(te,{...e})]})}const ae={expandButton:"expandButton_J3G9",expandButtonIcon:"expandButtonIcon_tUI1"};function oe(e){let{toggleSidebar:t}=e;return(0,b.jsx)("div",{className:ae.expandButton,title:(0,c.T)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t,children:(0,b.jsx)(_,{className:ae.expandButtonIcon})})}const ie={docSidebarContainer:"docSidebarContainer_cXIi",docSidebarContainerHidden:"docSidebarContainerHidden_ZUk8",sidebarViewport:"sidebarViewport_zEPt"};function se(e){let{children:t}=e;const n=(0,r.t)();return(0,b.jsx)(a.Fragment,{children:t},n?.name??"noSidebar")}function le(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:i}=e;const{pathname:l}=(0,x.zy)(),[r,c]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{r&&c(!1),!r&&(0,p.O)()&&c(!0),i((e=>!e))}),[i,r]);return(0,b.jsx)("aside",{className:(0,o.A)(s.G.docs.docSidebarContainer,ie.docSidebarContainer,n&&ie.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(ie.docSidebarContainer)&&n&&c(!0)},children:(0,b.jsx)(se,{children:(0,b.jsxs)("div",{className:(0,o.A)(ie.sidebarViewport,r&&ie.sidebarViewportHidden),children:[(0,b.jsx)(ne,{sidebar:t,path:l,onCollapse:d,isHidden:r}),r&&(0,b.jsx)(oe,{toggleSidebar:d})]})})})}const re={docMainContainer:"docMainContainer_ZDW3",docMainContainerEnhanced:"docMainContainerEnhanced__qER",docItemWrapperEnhanced:"docItemWrapperEnhanced_pzsv"};function ce(e){let{hiddenSidebarContainer:t,children:n}=e;const a=(0,r.t)();return(0,b.jsx)("main",{className:(0,o.A)(re.docMainContainer,(t||!a)&&re.docMainContainerEnhanced),children:(0,b.jsx)("div",{className:(0,o.A)("container padding-top--md padding-bottom--lg",re.docItemWrapper,t&&re.docItemWrapperEnhanced),children:n})})}const de={docRoot:"docRoot_QYMv",docsWrapper:"docsWrapper_xW7h"};function ue(e){let{children:t}=e;const n=(0,r.t)(),[o,i]=(0,a.useState)(!1);return(0,b.jsxs)("div",{className:de.docsWrapper,children:[(0,b.jsx)(h,{}),(0,b.jsxs)("div",{className:de.docRoot,children:[n&&(0,b.jsx)(le,{sidebar:n.items,hiddenSidebarContainer:o,setHiddenSidebarContainer:i}),(0,b.jsx)(ce,{hiddenSidebarContainer:o,children:t})]})]})}var me=n(1906);function be(e){const t=(0,l.B5)(e);if(!t)return(0,b.jsx)(me.A,{});const{docElement:n,sidebarName:a,sidebarItems:c}=t;return(0,b.jsx)(i.e3,{className:(0,o.A)(s.G.page.docsDocPage),children:(0,b.jsx)(r.V,{name:a,items:c,children:(0,b.jsx)(ue,{children:n})})})}},1906:(e,t,n)=>{n.d(t,{A:()=>l});n(758);var a=n(3526),o=n(7706),i=n(9663),s=n(6070);function l(e){let{className:t}=e;return(0,s.jsx)("main",{className:(0,a.A)("container margin-vert--xl",t),children:(0,s.jsx)("div",{className:"row",children:(0,s.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,s.jsx)(i.A,{as:"h1",className:"hero__title",children:(0,s.jsx)(o.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}}}]); \ No newline at end of file diff --git a/assets/js/aba21aa0.eb7bf6f2.js b/assets/js/aba21aa0.eb7bf6f2.js new file mode 100644 index 00000000..8df44791 --- /dev/null +++ b/assets/js/aba21aa0.eb7bf6f2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[742],{7093:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/bf6ec8e5.eeef95cf.js b/assets/js/bf6ec8e5.eeef95cf.js new file mode 100644 index 00000000..642e008a --- /dev/null +++ b/assets/js/bf6ec8e5.eeef95cf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[607],{8026:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var i=t(6070),s=t(5710);const o={id:"identity",title:"Identity"},r=void 0,a={id:"learn/core-concepts/identity",title:"Identity",description:"Key Management",source:"@site/docs/02-learn/03-core-concepts/01-identity (DID).mdx",sourceDirName:"02-learn/03-core-concepts",slug:"/learn/core-concepts/identity",permalink:"/learn/core-concepts/identity",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedAt:1718189423e3,sidebarPosition:1,frontMatter:{id:"identity",title:"Identity"},sidebar:"tutorialSidebar",previous:{title:"Terminology",permalink:"/learn/terminology"},next:{title:"Client Node",permalink:"/learn/core-concepts/node/client-node"}},l={},c=[{value:"Key Management",id:"key-management",level:3},{value:"Node Keys",id:"node-keys",level:3},{value:"Application Keys",id:"application-keys",level:3}];function d(e){const n={a:"a",h3:"h3",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h3,{id:"key-management",children:"Key Management"}),"\n",(0,i.jsx)(n.p,{children:"Calimero's key management is centered around two types: Node Keys for node management and Application Keys for app operation. This structure ensures secure, anonymous and decentralized control across the network."}),"\n",(0,i.jsx)(n.h3,{id:"node-keys",children:"Node Keys"}),"\n",(0,i.jsx)(n.p,{children:"Node Keys are used to for node operations which include, add new node keys, identifier listing, and key deletion. Web3 wallets can be used as node keys, easing the setup process."}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Key Initialization Process"}),":"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Starting Without Keys"}),": Initially, nodes have no keys. The addition of the first key is crucial for setting up application identities."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Adding the First Key"}),":","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["In the node admin UI, connect a wallet, such as MetaMask or Near wallets compliant with ",(0,i.jsx)(n.a,{href:"https://github.com/near/NEPs/blob/master/neps/nep-0413.md",children:"NEP-413"}),"."]}),"\n",(0,i.jsx)(n.li,{children:"Sign a challenge from the node and submit the signature."}),"\n",(0,i.jsx)(n.li,{children:"If the signature matches the challenge and the public key, the first node key is added, activating key management capabilities."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"application-keys",children:"Application Keys"}),"\n",(0,i.jsx)(n.p,{children:"Application Keys initiate applications, with keypairs stored in browser local storage."}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Application Key Usage"}),":"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Key Creation"}),": Users generate a new keypair in their browser."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Verification"}),":","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"A Verifiable Presentation Request is sent to the node, which responds with a challenge."}),"\n",(0,i.jsx)(n.li,{children:"The challenge and public key are signed using the node key."}),"\n",(0,i.jsx)(n.li,{children:"Upon node verification of the request and signature, the new key is cleared for JSONRPC API communication from the browser to the node."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Calimero's TypeScript SDK supports developers in building browser and CLI applications by simplifying interaction with the network."}),"\n",(0,i.jsx)(n.p,{children:"This key management setup underpins secure and efficient operations within the Calimero Network, facilitating both node and application functionalities."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},5710:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(758);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d84133a6.7b03dc69.js b/assets/js/d84133a6.7b03dc69.js new file mode 100644 index 00000000..adbd5b9a --- /dev/null +++ b/assets/js/d84133a6.7b03dc69.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[965],{4735:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var i=t(6070),s=t(5710);const r={id:"client-ts-sdk",title:"TypeScript Client SDK"},o=void 0,c={id:"build/client-sdks/client-ts-sdk",title:"TypeScript Client SDK",description:"Getting Started with Calimero SDK for Typescript",source:"@site/docs/03-build/02-client-sdks/02-client-ts-sdk.mdx",sourceDirName:"03-build/02-client-sdks",slug:"/build/client-sdks/client-ts-sdk",permalink:"/build/client-sdks/client-ts-sdk",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedAt:1718189423e3,sidebarPosition:2,frontMatter:{id:"client-ts-sdk",title:"TypeScript Client SDK"},sidebar:"tutorialSidebar",previous:{title:"Rust Protocol SDK",permalink:"/build/protocol-sdks/protocol-rs-sdk"},next:{title:"Publish App",permalink:"/build/publish-app"}},a={},l=[{value:"Getting Started with Calimero SDK for Typescript",id:"getting-started-with-calimero-sdk-for-typescript",level:2},{value:"Components",id:"components",level:3},{value:"RpcClient interface",id:"rpcclient-interface",level:4},{value:"SubscriptionsClient",id:"subscriptionsclient",level:4},{value:"Examples",id:"examples",level:3},{value:"JsonRpcClient",id:"jsonrpcclient",level:4},{value:"WsSubscriptionsClient",id:"wssubscriptionsclient",level:4}];function p(e){const n={code:"code",h2:"h2",h3:"h3",h4:"h4",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"getting-started-with-calimero-sdk-for-typescript",children:"Getting Started with Calimero SDK for Typescript"}),"\n",(0,i.jsx)(n.p,{children:"Our TypeScript Client SDK is a powerful tool designed to simplify the process of interacting with decentralized peer-to-peer applications installed on the node. It serves as an efficient conduit for communication between the client and the node\u2019s server. This SDK is particularly beneficial for developers as it abstracts the complexities of server communication, allowing them to concentrate on the core application logic."}),"\n",(0,i.jsx)(n.p,{children:"The SDK is built with the modern features of TypeScript, a language that is gaining popularity for its static typing and advanced capabilities. By using our SDK, developers can write applications in TypeScript, and the SDK takes care of the rest. It handles all the interactions with the server, making the development process more streamlined and efficient."}),"\n",(0,i.jsx)(n.p,{children:"This not only enhances the overall development experience but also accelerates the deployment of innovative decentralized applications on our network. In essence, our TypeScript SDK is a comprehensive solution that makes building and interacting with decentralized applications a breeze. It\u2019s all about making the development process more enjoyable and productive for developers worldwide."}),"\n",(0,i.jsx)(n.h3,{id:"components",children:"Components"}),"\n",(0,i.jsxs)(n.p,{children:["Our TypeScript Client SDK is composed of two main components: ",(0,i.jsx)(n.code,{children:"RpcClient"})," and ",(0,i.jsx)(n.code,{children:"SubscriptionsClient"}),". Each of these components has an interface and a class that implements the interface. The ",(0,i.jsx)(n.code,{children:"RpcClient"})," interface is implemented by the ",(0,i.jsx)(n.code,{children:"JsonRpcClient"})," class, and the ",(0,i.jsx)(n.code,{children:"SubscriptionsClient"})," interface is implemented by the ",(0,i.jsx)(n.code,{children:"WsSubscriptionsClient"})," class."]}),"\n",(0,i.jsx)(n.p,{children:"These components are designed with flexibility and future growth in mind. While currently there is only one implementation of each interface, we anticipate multiple implementations in the future. This is because our server will have multiple implementations of both the Rpc server and the Subscriptions server. This design allows us to easily add new classes that implement these interfaces as our server capabilities expand."}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"RpcClient"})," and ",(0,i.jsx)(n.code,{children:"SubscriptionsClient"})," interfaces define a standard set of methods that all implementations must provide. This ensures consistency across different implementations, making it easier for developers to switch between different Rpc and Subscriptions servers as needed."]}),"\n",(0,i.jsx)(n.p,{children:"By designing our SDK in this way, we ensure that it remains flexible, scalable, and easy to use, regardless of how our server implementations evolve in the future."}),"\n",(0,i.jsx)(n.h4,{id:"rpcclient-interface",children:"RpcClient interface"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:"export interface RpcClient {\n query (\n params: RpcQueryParams ,\n config?: RequestConfig\n ): Promise >;\n mutate (\n params: RpcMutateParams ,\n config?: RequestConfig\n ): Promise >;\n}\n\nexport interface RequestConfig {\n timeout?: number;\n}\n\nexport interface RpcQueryParams {\n applicationId: ApplicationId;\n method: string;\n argsJson: Args;\n}\n\nexport interface RpcQueryResponse