1"use strict";(self.webpackChunkwalletconnect_docs=self.webpackChunkwalletconnect_docs||[]).push([[223],{89253:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>r});var l=s(13274),n=s(79449);const c={title:"Relay"},i=void 0,o={id:"cloud/relay",title:"Relay",description:"Project ID",source:"@site/docs/cloud/relay.mdx",sourceDirName:"cloud",slug:"/cloud/relay",permalink:"/cloud/relay",draft:!1,unlisted:!1,editUrl:"https://github.com/WalletConnect/walletconnect-docs/blob/main/docs/cloud/relay.mdx",tags:[],version:"current",lastUpdatedAt:1740270108e3,frontMatter:{title:"Relay"},sidebar:"mainSidebar",previous:{title:"Verify",permalink:"/cloud/verify"},next:{title:"Blockchain API",permalink:"/cloud/blockchain-api"}},d={},r=[{value:"Project ID",id:"project-id",level:2},{value:"Allowlist",id:"allowlist",level:2},{value:"Error Codes",id:"error-codes",level:2},{value:"Websocket Close Codes",id:"websocket-close-codes",level:2},{value:"Best Practices",id:"best-practices",level:2}];function a(e){const t={a:"a",code:"code",h2:"h2",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,n.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(t.h2,{id:"project-id",children:"Project ID"}),"\n",(0,l.jsx)(t.p,{children:"The Project ID is consumed through URL parameters."}),"\n",(0,l.jsx)(t.p,{children:"URL parameters used:"}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsxs)(t.li,{children:[(0,l.jsx)(t.code,{children:"projectId"}),": Your Project ID can be obtained from ",(0,l.jsx)(t.a,{href:"https://walletconnect.com",children:"walletconnect.com"})]}),"\n"]}),"\n",(0,l.jsx)(t.p,{children:"Example URL:"}),"\n",(0,l.jsx)(t.p,{children:(0,l.jsx)(t.code,{children:"https://relay.walletconnect.com/?projectId=c4f79cc821944d9680842e34466bfbd"})}),"\n",(0,l.jsxs)(t.p,{children:["This can be instantiated from the client with the ",(0,l.jsx)(t.code,{children:"projectId"})," in the ",(0,l.jsx)(t.code,{children:"SignClient"})," constructor."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-javascript",children:"import SignClient from '@walletconnect/sign-client'\nconst signClient = await SignClient.init({\n projectId: 'c4f79cc821944d9680842e34466bfb'\n})\n"})}),"\n",(0,l.jsx)(t.h2,{id:"allowlist",children:"Allowlist"}),"\n",(0,l.jsxs)(t.p,{children:["To help prevent malicious use of your project ID you are strongly encouraged to set an allowlist of ",(0,l.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin",children:"origins"})," or application/bundle ids for mobile applications where the project ID is used. Requests from other origins will be denied."]}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsxs)(t.li,{children:["Allowlist supports a list of origins in the format ",(0,l.jsx)(t.code,{children:"[scheme://]<hostname[:port]"}),"."]}),"\n",(0,l.jsxs)(t.li,{children:[(0,l.jsx)(t.a,{href:"https://developer.android.com/build/configure-app-module#set-application-id",children:"Application ID"}),"/",(0,l.jsx)(t.a,{href:"https://developer.apple.com/documentation/appstoreconnectapi/bundle_ids",children:"Bundle IDs"})," typically are defined using the ",(0,l.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Reverse_domain_name_notation",children:"reverse domain name notation"})]}),"\n"]}),"\n",(0,l.jsxs)(t.p,{children:["Using ",(0,l.jsx)(t.code,{children:"localhost"})," (or ",(0,l.jsx)(t.code,{children:"127.0.0.1"}),") is always permitted, and if empty all origins are allowed. Updates take 15 minutes to apply."]}),"\n",(0,l.jsx)(t.p,{children:"If scheme or port is specified, it must match exactly. Hostname must also match exactly, but wildcards can be used for individual labels within the hostname."}),"\n",(0,l.jsx)(t.p,{children:"Example of possible origins in the allowlist:"}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsxs)(t.li,{children:[(0,l.jsx)(t.code,{children:"example.com"})," - allows ",(0,l.jsx)(t.code,{children:"https://example.com"})," or ",(0,l.jsx)(t.code,{children:"http://example.com"})," but not ",(0,l.jsx)(t.code,{children:"https://www.example.com"})]}),"\n",(0,l.jsxs)(t.li,{children:[(0,l.jsx)(t.code,{children:"https://example.com"})," - allows ",(0,l.jsx)(t.code,{children:"https://example.com"})," but not ",(0,l.jsx)(t.code,{children:"http://example.com"})]}),"\n",(0,l.jsxs)(t.li,{children:[(0,l.jsx)(t.code,{children:"https://www.example.com"})," - allows ",(0,l.jsx)(t.code,{children:"https://www.example.com"})," but not ",(0,l.jsx)(t.code,{children:"https://example.com"})]}),"\n",(0,l.jsxs)(t.li,{children:[(0,l.jsx)(t.code,{children:"https://example.com:8080"})," - allows ",(0,l.jsx)(t.code,{children:"https://example.com:8080"})," but not ",(0,l.jsx)(t.code,{children:"https://example.com"})]}),"\n",(0,l.jsxs)(t.li,{children:[(0,l.jsx)(t.code,{children:"https://*.example.com"})," - allows ",(0,l.jsx)(t.code,{children:"https://www.example.com"})," but not ",(0,l.jsx)(t.code,{children:"https://example.com"})]}),"\n",(0,l.jsxs)(t.li,{children:[(0,l.jsx)(t.code,{children:"https://*.*.example.com"})," - allows ",(0,l.jsx)(t.code,{children:"https://www.subdomain.example.com"})," but not ",(0,l.jsx)(t.code,{children:"https://www.example.com"})," or ",(0,l.jsx)(t.code,{children:"https://example.com"})]}),"\n",(0,l.jsxs)(t.li,{children:[(0,l.jsx)(t.code,{children:"https://www.*.example.com"})," - allows ",(0,l.jsx)(t.code,{children:"https://www.subdomain.example.com"})," but not ",(0,l.jsx)(t.code,{children:"https://www.example.com"})]}),"\n",(0,l.jsxs)(t.li,{children:[(0,l.jsx)(t.code,{children:"https://www-*.example.com"})," - invalid; ",(0,l.jsx)(t.code,{children:"*"})," must be the full label"]}),"\n"]}),"\n",(0,l.jsx)(t.h2,{id:"error-codes",children:"Error Codes"}),"\n",(0,l.jsxs)(t.table,{children:[(0,l.jsx)(t.thead,{children:(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.th,{children:"Reason"}),(0,l.jsx)(t.th,{children:"Error Code"})]})}),(0,l.jsxs)(t.tbody,{children:[(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{children:"Project ID doesn't exist OR JWT is expired"}),(0,l.jsx)(t.td,{children:"401"})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{children:"Exists and is invali
1d"}),(0,l.jsx)(t.td,{children:"403"})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{children:"Too many requests"}),(0,l.jsx)(t.td,{children:"1013"})]})]})]}),"\n",(0,l.jsx)(t.h2,{id:"websocket-close-codes",children:"Websocket Close Codes"}),"\n",(0,l.jsxs)(t.table,{children:[(0,l.jsx)(t.thead,{children:(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.th,{children:"Code"}),(0,l.jsx)(t.th,{children:"Description"}),(0,l.jsx)(t.th,{children:"Reconnect"})]})}),(0,l.jsxs)(t.tbody,{children:[(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{children:"1001"}),(0,l.jsx)(t.td,{children:"Server terminating"}),(0,l.jsx)(t.td,{children:"Yes"})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{children:"4008"}),(0,l.jsx)(t.td,{children:"Client stale: connected without a prior subscription and is not sending data"}),(0,l.jsx)(t.td,{children:"When needed"})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{children:"4010"}),(0,l.jsx)(t.td,{children:"Load Rebalancing"}),(0,l.jsx)(t.td,{children:"Yes"})]})]})]}),"\n",(0,l.jsx)(t.h2,{id:"best-practices",children:"Best Practices"}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsxs)(t.li,{children:["Create a new ",(0,l.jsx)(t.code,{children:"projectId"})," for each project. This allows for more granular control, dedicated explorer listings, and project metrics."]}),"\n",(0,l.jsxs)(t.li,{children:["Don't reuse a ",(0,l.jsx)(t.code,{children:"projectId"}),"."]}),"\n",(0,l.jsx)(t.li,{children:"Use the AllowList to limit unauthorized usage."}),"\n",(0,l.jsx)(t.li,{children:"Avoid committing projects keys to the repo. Use env variables instead."}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,l.jsx)(t,{...e,children:(0,l.jsx)(a,{...e})}):a(e)}},79449:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>o});var l=s(79474);const n={},c=l.createContext(n);function i(e){const t=l.useContext(c);return l.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),l.createElement(c.Provider,{value:t},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.