UNPKG

@walletconnect/core

Version:
1 lines 74.2 kB
import Ne,{EventEmitter as z}from"events";import{HEARTBEAT_EVENTS as K,HeartBeat as ke}from"@walletconnect/heartbeat";import Le from"@walletconnect/keyvaluestorage";import{generateChildLogger as f,getLoggerContext as I,getDefaultLoggerOptions as De,generatePlatformLogger as ze}from"@walletconnect/logger";import{IMessageTracker as Ke,IPublisher as Me,ISubscriber as $e,IRelayer as Ue,IStore as qe,IJsonRpcHistory as Ve,IExpirer as Be,IVerify as Fe,IEchoClient as Ge,IEventClient as We,ICore as He}from"@walletconnect/types";import{ONE_DAY as M,SIX_HOURS as Ye,THIRTY_DAYS as et,FIVE_SECONDS as it,THIRTY_SECONDS as J,toMiliseconds as y,ONE_MINUTE as ut,ONE_SECOND as A,FIVE_MINUTES as V,fromMiliseconds as yt}from"@walletconnect/time";import{safeJsonStringify as Je,safeJsonParse as mt}from"@walletconnect/safe-json";import*as j from"@walletconnect/relay-auth";import{decodeJWT as _t}from"@walletconnect/relay-auth";import{fromString as je}from"uint8arrays/from-string";import{getInternalError as c,mapToObj as st,objToMap as rt,generateRandomBytes32 as ot,generateKeyPair as Xe,deriveSymKey as Ze,hashKey as Qe,validateEncoding as ti,isTypeTwoEnvelope as bt,encodeTypeTwoEnvelope as ei,isTypeOneEnvelope as wt,encrypt as ii,validateDecoding as si,decodeTypeTwoEnvelope as ri,decrypt as oi,BASE64 as ft,deserialize as vt,decodeTypeByte as ni,BASE16 as ai,hashMessage as X,getRelayProtocolApi as $,getRelayProtocolName as Z,isUndefined as B,createExpiringPromise as R,getSdkError as F,sleep as hi,isNode as Et,createLogger as ci,isAndroid as li,getAppId as It,isIos as gi,isOnline as Tt,calcExpiry as G,formatRelayRpcUrl as pi,subscribeToNetworkChange as di,isAppVisible as ui,isProposalStruct as yi,isSessionStruct as mi,TYPE_1 as _i,formatUri as Pt,parseUri as Rt,createDelayedPromise as bi,engineEvent as nt,isExpired as St,isValidParams as at,isValidUrl as wi,isValidString as fi,parseExpirerTarget as vi,formatTopicTarget as Ei,formatIdTarget as Ii,isBrowser as Ti,verifyP256Jwt as Pi,isTestRun as Ct,formatUA as Ri,uuidv4 as xt,getAppMetadata as Si}from"@walletconnect/utils";import{toString as Ci}from"uint8arrays";import{JsonRpcProvider as xi}from"@walletconnect/jsonrpc-provider";import{getBigIntRpcId as ht,isJsonRpcRequest as Ot,isJsonRpcResponse as At,formatJsonRpcResult as Nt,formatJsonRpcRequest as kt,formatJsonRpcError as Oi,isJsonRpcResult as Ai,isJsonRpcError as Lt}from"@walletconnect/jsonrpc-utils";import Ni from"@walletconnect/jsonrpc-ws-connection";import{isEqual as ki}from"es-toolkit/compat";import{getDocument as Li}from"@walletconnect/window-getters";const ct="wc",lt=2,W="core",S=`${ct}@2:${W}:`,Dt={name:W,logger:"error"},zt={database:":memory:"},Kt="crypto",gt="client_ed25519_seed",Mt=M,$t="keychain",Ut="0.3",qt="messages",Vt="0.3",Bt=Ye,Ft="publisher",Gt="irn",Wt="error",pt="wss://relay.walletconnect.org",Ht="relayer",p={message:"relayer_message",message_ack:"relayer_message_ack",connect:"relayer_connect",disconnect:"relayer_disconnect",error:"relayer_error",connection_stalled:"relayer_connection_stalled",transport_closed:"relayer_transport_closed",publish:"relayer_publish"},Yt="_subscription",v={payload:"payload",connect:"connect",disconnect:"disconnect",error:"error"},Jt=.1,Di={database:":memory:"},Q="2.23.9",zi=1e4,D={link_mode:"link_mode",relay:"relay"},H={inbound:"inbound",outbound:"outbound"},jt="0.3",Xt="WALLETCONNECT_CLIENT_ID",dt="WALLETCONNECT_LINK_MODE_APPS",b={created:"subscription_created",deleted:"subscription_deleted",expired:"subscription_expired",disabled:"subscription_disabled",sync:"subscription_sync",resubscribed:"subscription_resubscribed"},Ki=et,Zt="subscription",Qt="0.3",Mi=it*1e3,te="pairing",ee="0.3",$i=et,U={wc_pairingDelete:{req:{ttl:M,prompt:!1,tag:1e3},res:{ttl:M,prompt:!1,tag:1001}},wc_pairingPing:{req:{ttl:J,prompt:!1,tag:1002},res:{ttl:J,prompt:!1,tag:1003}},unregistered_method:{req:{ttl:M,prompt:!1,tag:0},res:{ttl:M,prompt:!1,tag:0}}},q={create:"pairing_create",expire:"pairing_expire",delete:"pairing_delete",ping:"pairing_ping"},T={created:"history_created",updated:"history_updated",deleted:"history_deleted",sync:"history_sync"},ie="history",se="0.3",re="expirer",P={created:"expirer_created",deleted:"expirer_deleted",expired:"expirer_expired",sync:"expirer_sync"},oe="0.3",Ui=M,ne="verify-api",qi="https://verify.walletconnect.com",ae="https://verify.walletconnect.org",Y=ae,he=`${Y}/v3`,ce=[qi,ae],le="echo",ge="https://echo.walletconnect.com",Vi="event-client",x={pairing_started:"pairing_started",pairing_uri_validation_success:"pairing_uri_validation_success",pairing_uri_not_expired:"pairing_uri_not_expired",store_new_pairing:"store_new_pairing",subscribing_pairing_topic:"subscribing_pairing_topic",subscribe_pairing_topic_success:"subscribe_pairing_topic_success",existing_pairing:"existing_pairing",pairing_not_expired:"pairing_not_expired",emit_inactive_pairing:"emit_inactive_pairing",emit_session_proposal:"emit_session_proposal",subscribing_to_pairing_topic:"subscribing_to_pairing_topic"},O={no_wss_connection:"no_wss_connection",no_internet_connection:"no_internet_connection",malformed_pairing_uri:"malformed_pairing_uri",active_pairing_already_exists:"active_pairing_already_exists",subscribe_pairing_topic_failure:"subscribe_pairing_topic_failure",pairing_expired:"pairing_expired",proposal_expired:"proposal_expired",proposal_listener_not_found:"proposal_listener_not_found"},Bi={session_approve_started:"session_approve_started",proposal_not_expired:"proposal_not_expired",session_namespaces_validation_success:"session_namespaces_validation_success",create_session_topic:"create_session_topic",subscribing_session_topic:"subscribing_session_topic",subscribe_session_topic_success:"subscribe_session_topic_success",publishing_session_approve:"publishing_session_approve",session_approve_publish_success:"session_approve_publish_success",store_session:"store_session",publishing_session_settle:"publishing_session_settle",session_settle_publish_success:"session_settle_publish_success",session_request_response_started:"session_request_response_started",session_request_response_validation_success:"session_request_response_validation_success",session_request_response_publish_started:"session_request_response_publish_started"},Fi={no_internet_connection:"no_internet_connection",no_wss_connection:"no_wss_connection",proposal_expired:"proposal_expired",subscribe_session_topic_failure:"subscribe_session_topic_failure",session_approve_publish_failure:"session_approve_publish_failure",session_settle_publish_failure:"session_settle_publish_failure",session_approve_namespace_validation_failure:"session_approve_namespace_validation_failure",proposal_not_found:"proposal_not_found",session_request_response_validation_failure:"session_request_response_validation_failure",session_request_response_publish_failure:"session_request_response_publish_failure"},Gi={authenticated_session_approve_started:"authenticated_session_approve_started",authenticated_session_not_expired:"authenticated_session_not_expired",chains_caip2_compliant:"chains_caip2_compliant",chains_evm_compliant:"chains_evm_compliant",create_authenticated_session_topic:"create_authenticated_session_topic",cacaos_verified:"cacaos_verified",store_authenticated_session:"store_authenticated_session",subscribing_authenticated_session_topic:"subscribing_authenticated_session_topic",subscribe_authenticated_session_topic_success:"subscribe_authenticated_session_topic_success",publishing_authenticated_session_approve:"publishing_authenticated_session_approve",authenticated_session_approve_publish_success:"authenticated_session_approve_publish_success"},Wi={no_internet_connection:"no_internet_connection",no_wss_connection:"no_wss_connection",missing_session_authenticate_request:"missing_session_authenticate_request",session_authenticate_request_expired:"session_authenticate_request_expired",chains_caip2_compliant_failure:"chains_caip2_compliant_failure",chains_evm_compliant_failure:"chains_evm_compliant_failure",invalid_cacao:"invalid_cacao",subscribe_authenticated_session_topic_failure:"subscribe_authenticated_session_topic_failure",authenticated_session_approve_publish_failure:"authenticated_session_approve_publish_failure",authenticated_session_pending_request_not_found:"authenticated_session_pending_request_not_found"},pe=.1,de="event-client",ue=86400,ye="https://pulse.walletconnect.org/batch";class me{constructor(t,s){this.core=t,this.logger=s,this.keychain=new Map,this.name=$t,this.version=Ut,this.initialized=!1,this.storagePrefix=S,this.init=async()=>{if(!this.initialized){const i=await this.getKeyChain();typeof i<"u"&&(this.keychain=i),this.initialized=!0}},this.has=i=>(this.isInitialized(),this.keychain.has(i)),this.set=async(i,e)=>{this.isInitialized(),this.keychain.set(i,e),await this.persist()},this.get=i=>{this.isInitialized();const e=this.keychain.get(i);if(typeof e>"u"){const{message:r}=c("NO_MATCHING_KEY",`${this.name}: ${i}`);throw new Error(r)}return e},this.del=async i=>{this.isInitialized(),this.keychain.delete(i),await this.persist()},this.core=t,this.logger=f(s,this.name)}get context(){return I(this.logger)}get storageKey(){return this.storagePrefix+this.version+this.core.customStoragePrefix+"//"+this.name}async setKeyChain(t){await this.core.storage.setItem(this.storageKey,st(t))}async getKeyChain(){const t=await this.core.storage.getItem(this.storageKey);return typeof t<"u"?rt(t):void 0}async persist(){await this.setKeyChain(this.keychain)}isInitialized(){if(!this.initialized){const{message:t}=c("NOT_INITIALIZED",this.name);throw new Error(t)}}}class _e{constructor(t,s,i){this.core=t,this.logger=s,this.name=Kt,this.randomSessionIdentifier=ot(),this.initialized=!1,this.init=async()=>{this.initialized||(await this.keychain.init(),this.initialized=!0)},this.hasKeys=e=>(this.isInitialized(),this.keychain.has(e)),this.getClientId=async()=>{if(this.isInitialized(),this.clientId)return this.clientId;const e=await this.getClientSeed(),r=j.generateKeyPair(e),o=j.encodeIss(r.publicKey);return this.clientId=o,o},this.generateKeyPair=()=>{this.isInitialized();const e=Xe();return this.setPrivateKey(e.publicKey,e.privateKey)},this.signJWT=async e=>{this.isInitialized();const r=await this.getClientSeed(),o=j.generateKeyPair(r),n=this.randomSessionIdentifier,a=Mt;return await j.signJWT(n,e,a,o)},this.generateSharedKey=(e,r,o)=>{this.isInitialized();const n=this.getPrivateKey(e),a=Ze(n,r);return this.setSymKey(a,o)},this.setSymKey=async(e,r)=>{this.isInitialized();const o=r||Qe(e);return await this.keychain.set(o,e),o},this.deleteKeyPair=async e=>{this.isInitialized(),await this.keychain.del(e)},this.deleteSymKey=async e=>{this.isInitialized(),await this.keychain.del(e)},this.encode=async(e,r,o)=>{this.isInitialized();const n=ti(o),a=Je(r);if(bt(n))return ei(a,o?.encoding);if(wt(n)){const g=n.senderPublicKey,_=n.receiverPublicKey;e=await this.generateSharedKey(g,_)}const h=this.getSymKey(e),{type:d,senderPublicKey:l}=n;return ii({type:d,symKey:h,message:a,senderPublicKey:l,encoding:o?.encoding})},this.decode=async(e,r,o)=>{this.isInitialized();const n=si(r,o);if(bt(n)){const a=ri(r,o?.encoding);return mt(a)}if(wt(n)){const a=n.receiverPublicKey,h=n.senderPublicKey;e=await this.generateSharedKey(a,h)}try{const a=this.getSymKey(e),h=oi({symKey:a,encoded:r,encoding:o?.encoding});return mt(h)}catch(a){this.logger.error(`Failed to decode message from topic: '${e}', clientId: '${await this.getClientId()}'`),this.logger.error(a)}},this.getPayloadType=(e,r=ft)=>{const o=vt({encoded:e,encoding:r});return ni(o.type)},this.getPayloadSenderPublicKey=(e,r=ft)=>{const o=vt({encoded:e,encoding:r});return o.senderPublicKey?Ci(o.senderPublicKey,ai):void 0},this.core=t,this.logger=f(s,this.name),this.keychain=i||new me(this.core,this.logger)}get context(){return I(this.logger)}async setPrivateKey(t,s){return await this.keychain.set(t,s),t}getPrivateKey(t){return this.keychain.get(t)}async getClientSeed(){let t="";try{t=this.keychain.get(gt)}catch{t=ot(),await this.keychain.set(gt,t)}return je(t,"base16")}getSymKey(t){return this.keychain.get(t)}isInitialized(){if(!this.initialized){const{message:t}=c("NOT_INITIALIZED",this.name);throw new Error(t)}}}class be extends Ke{constructor(t,s){super(t,s),this.logger=t,this.core=s,this.messages=new Map,this.messagesWithoutClientAck=new Map,this.name=qt,this.version=Vt,this.initialized=!1,this.storagePrefix=S,this.init=async()=>{if(!this.initialized){this.logger.trace("Initialized");try{const i=await this.getRelayerMessages();typeof i<"u"&&(this.messages=i);const e=await this.getRelayerMessagesWithoutClientAck();typeof e<"u"&&(this.messagesWithoutClientAck=e),this.logger.debug(`Successfully Restored records for ${this.name}`),this.logger.trace({type:"method",method:"restore",size:this.messages.size})}catch(i){this.logger.debug(`Failed to Restore records for ${this.name}`),this.logger.error(i)}finally{this.initialized=!0}}},this.set=async(i,e,r)=>{this.isInitialized();const o=X(e);let n=this.messages.get(i);if(typeof n>"u"&&(n={}),typeof n[o]<"u")return o;if(n[o]=e,this.messages.set(i,n),r===H.inbound){const a=this.messagesWithoutClientAck.get(i)||{};this.messagesWithoutClientAck.set(i,{...a,[o]:e})}return await this.persist(),o},this.get=i=>{this.isInitialized();let e=this.messages.get(i);return typeof e>"u"&&(e={}),e},this.getWithoutAck=i=>{this.isInitialized();const e={};for(const r of i){const o=this.messagesWithoutClientAck.get(r)||{};e[r]=Object.values(o)}return e},this.has=(i,e)=>{this.isInitialized();const r=this.get(i),o=X(e);return typeof r[o]<"u"},this.ack=async(i,e)=>{this.isInitialized();const r=this.messagesWithoutClientAck.get(i);if(typeof r>"u")return;const o=X(e);delete r[o],Object.keys(r).length===0?this.messagesWithoutClientAck.delete(i):this.messagesWithoutClientAck.set(i,r),await this.persist()},this.del=async i=>{this.isInitialized(),this.messages.delete(i),this.messagesWithoutClientAck.delete(i),await this.persist()},this.logger=f(t,this.name),this.core=s}get context(){return I(this.logger)}get storageKey(){return this.storagePrefix+this.version+this.core.customStoragePrefix+"//"+this.name}get storageKeyWithoutClientAck(){return this.storagePrefix+this.version+this.core.customStoragePrefix+"//"+this.name+"_withoutClientAck"}async setRelayerMessages(t){await this.core.storage.setItem(this.storageKey,st(t))}async setRelayerMessagesWithoutClientAck(t){await this.core.storage.setItem(this.storageKeyWithoutClientAck,st(t))}async getRelayerMessages(){const t=await this.core.storage.getItem(this.storageKey);return typeof t<"u"?rt(t):void 0}async getRelayerMessagesWithoutClientAck(){const t=await this.core.storage.getItem(this.storageKeyWithoutClientAck);return typeof t<"u"?rt(t):void 0}async persist(){await this.setRelayerMessages(this.messages),await this.setRelayerMessagesWithoutClientAck(this.messagesWithoutClientAck)}isInitialized(){if(!this.initialized){const{message:t}=c("NOT_INITIALIZED",this.name);throw new Error(t)}}}class Hi extends Me{constructor(t,s){super(t,s),this.relayer=t,this.logger=s,this.events=new z,this.name=Ft,this.queue=new Map,this.publishTimeout=y(ut),this.initialPublishTimeout=y(A*15),this.needsTransportRestart=!1,this.publish=async(i,e,r)=>{this.logger.debug("Publishing Payload"),this.logger.trace({type:"method",method:"publish",params:{topic:i,message:e,opts:r}});const o=r?.ttl||Bt,n=r?.prompt||!1,a=r?.tag||0,h=r?.id||ht().toString(),d=$(Z().protocol),l={id:h,method:r?.publishMethod||d.publish,params:{topic:i,message:e,ttl:o,prompt:n,tag:a,attestation:r?.attestation,...r?.tvf}},g=`Failed to publish payload, please try again. id:${h} tag:${a}`;try{B(l.params?.prompt)&&delete l.params?.prompt,B(l.params?.tag)&&delete l.params?.tag;const _=new Promise(async E=>{const u=({id:m})=>{l.id?.toString()===m.toString()&&(this.removeRequestFromQueue(m),this.relayer.events.removeListener(p.publish,u),E())};this.relayer.events.on(p.publish,u);const N=R(new Promise((m,C)=>{this.rpcPublish(l,r).then(m).catch(k=>{this.logger.warn(k,k?.message),C(k)})}),this.initialPublishTimeout,`Failed initial publish, retrying.... id:${h} tag:${a}`);try{await N,this.events.removeListener(p.publish,u)}catch(m){this.queue.set(h,{request:l,opts:r,attempt:1}),this.logger.warn(m,m?.message)}});this.logger.trace({type:"method",method:"publish",params:{id:h,topic:i,message:e,opts:r}}),await R(_,this.publishTimeout,g)}catch(_){if(this.logger.debug("Failed to Publish Payload"),this.logger.error(_),r?.internal?.throwOnFailedPublish)throw _}finally{this.queue.delete(h)}},this.publishCustom=async i=>{this.logger.debug("Publishing custom payload"),this.logger.trace({type:"method",method:"publishCustom",params:i});const{payload:e,opts:r={}}=i,{attestation:o,tvf:n,publishMethod:a,prompt:h,tag:d,ttl:l=V}=r,g=r.id||ht().toString(),_=$(Z().protocol),E=a||_.publish,u={id:g,method:E,params:{...e,ttl:l,prompt:h,tag:d,attestation:o,...n}},N=`Failed to publish custom payload, please try again. id:${g} tag:${d}`;try{B(u.params?.prompt)&&delete u.params?.prompt,B(u.params?.tag)&&delete u.params?.tag;const m=new Promise(async C=>{const k=({id:L})=>{u.id?.toString()===L.toString()&&(this.removeRequestFromQueue(L),this.relayer.events.removeListener(p.publish,k),C())};this.relayer.events.on(p.publish,k);const Oe=R(new Promise((L,Ae)=>{this.rpcPublish(u,r).then(L).catch(tt=>{this.logger.warn(tt,tt?.message),Ae(tt)})}),this.initialPublishTimeout,`Failed initial custom payload publish, retrying.... method:${E} id:${g} tag:${d}`);try{await Oe,this.events.removeListener(p.publish,k)}catch(L){this.queue.set(g,{request:u,opts:r,attempt:1}),this.logger.warn(L,L?.message)}});this.logger.trace({type:"method",method:"publish",params:{id:g,payload:e,opts:r}}),await R(m,this.publishTimeout,N)}catch(m){if(this.logger.debug("Failed to Publish Payload"),this.logger.error(m),r?.internal?.throwOnFailedPublish)throw m}finally{this.queue.delete(g)}},this.on=(i,e)=>{this.events.on(i,e)},this.once=(i,e)=>{this.events.once(i,e)},this.off=(i,e)=>{this.events.off(i,e)},this.removeListener=(i,e)=>{this.events.removeListener(i,e)},this.relayer=t,this.logger=f(s,this.name),this.registerEventListeners()}get context(){return I(this.logger)}async rpcPublish(t,s){this.logger.debug("Outgoing Relay Payload"),this.logger.trace({type:"message",direction:"outgoing",request:t});const i=await this.relayer.request(t);return this.relayer.events.emit(p.publish,{...t,...s}),this.logger.debug("Successfully Published Payload"),i}removeRequestFromQueue(t){this.queue.delete(t)}checkQueue(){this.queue.forEach(async(t,s)=>{const i=t.attempt+1;this.queue.set(s,{...t,attempt:i}),this.logger.warn({},`Publisher: queue->publishing: ${t.request.id}, tag: ${t.request.params?.tag}, attempt: ${i}`),await this.rpcPublish(t.request,t.opts),this.logger.warn({},`Publisher: queue->published: ${t.request.id}`)})}registerEventListeners(){this.relayer.core.heartbeat.on(K.pulse,()=>{if(this.needsTransportRestart){this.needsTransportRestart=!1,this.relayer.events.emit(p.connection_stalled);return}this.checkQueue()}),this.relayer.on(p.message_ack,t=>{this.removeRequestFromQueue(t.id.toString())})}}class Yi{constructor(){this.map=new Map,this.set=(t,s)=>{const i=this.get(t);this.exists(t,s)||this.map.set(t,[...i,s])},this.get=t=>this.map.get(t)||[],this.exists=(t,s)=>this.get(t).includes(s),this.delete=(t,s)=>{if(typeof s>"u"){this.map.delete(t);return}if(!this.map.has(t))return;const i=this.get(t);if(!this.exists(t,s))return;const e=i.filter(r=>r!==s);if(!e.length){this.map.delete(t);return}this.map.set(t,e)},this.clear=()=>{this.map.clear()}}get topics(){return Array.from(this.map.keys())}}class we extends $e{constructor(t,s){super(t,s),this.relayer=t,this.logger=s,this.subscriptions=new Map,this.topicMap=new Yi,this.events=new z,this.name=Zt,this.version=Qt,this.pending=new Map,this.cached=[],this.initialized=!1,this.storagePrefix=S,this.subscribeTimeout=y(ut),this.initialSubscribeTimeout=y(A*15),this.batchSubscribeTopicsLimit=500,this.init=async()=>{this.initialized||(this.logger.trace("Initialized"),this.registerEventListeners(),await this.restore()),this.initialized=!0},this.subscribe=async(i,e)=>{this.isInitialized(),this.logger.debug("Subscribing Topic"),this.logger.trace({type:"method",method:"subscribe",params:{topic:i,opts:e}});try{const r=Z(e),o={topic:i,relay:r,transportType:e?.transportType};e?.internal?.skipSubscribe||this.pending.set(i,o);const n=await this.rpcSubscribe(i,r,e);return typeof n=="string"&&(this.onSubscribe(n,o),this.logger.debug("Successfully Subscribed Topic"),this.logger.trace({type:"method",method:"subscribe",params:{topic:i,opts:e}})),n}catch(r){throw this.logger.debug("Failed to Subscribe Topic"),this.logger.error(r),r}},this.unsubscribe=async(i,e)=>{this.isInitialized(),typeof e?.id<"u"?await this.unsubscribeById(i,e.id,e):await this.unsubscribeByTopic(i,e)},this.isSubscribed=i=>new Promise(e=>{e(this.topicMap.topics.includes(i))}),this.isKnownTopic=i=>new Promise(e=>{e(this.topicMap.topics.includes(i)||this.pending.has(i)||this.cached.some(r=>r.topic===i))}),this.on=(i,e)=>{this.events.on(i,e)},this.once=(i,e)=>{this.events.once(i,e)},this.off=(i,e)=>{this.events.off(i,e)},this.removeListener=(i,e)=>{this.events.removeListener(i,e)},this.start=async()=>{await this.onConnect()},this.stop=async()=>{await this.onDisconnect()},this.restart=async()=>{await this.restore(),await this.onRestart()},this.checkPending=async()=>{if(this.pending.size===0&&(!this.initialized||!this.relayer.connected))return;const i=[];this.pending.forEach(e=>{i.push(e)}),await this.batchSubscribe(i)},this.registerEventListeners=()=>{this.relayer.core.heartbeat.on(K.pulse,async()=>{await this.checkPending()}),this.events.on(b.created,async i=>{const e=b.created;this.logger.info(`Emitting ${e}`),this.logger.debug({type:"event",event:e,data:i}),await this.persist()}),this.events.on(b.deleted,async i=>{const e=b.deleted;this.logger.info(`Emitting ${e}`),this.logger.debug({type:"event",event:e,data:i}),await this.persist()})},this.relayer=t,this.logger=f(s,this.name),this.clientId=""}get context(){return I(this.logger)}get storageKey(){return this.storagePrefix+this.version+this.relayer.core.customStoragePrefix+"//"+this.name}get length(){return this.subscriptions.size}get ids(){return Array.from(this.subscriptions.keys())}get values(){return Array.from(this.subscriptions.values())}get topics(){return this.topicMap.topics}get hasAnyTopics(){return this.topicMap.topics.length>0||this.pending.size>0||this.cached.length>0||this.subscriptions.size>0}hasSubscription(t,s){let i=!1;try{i=this.getSubscription(t).topic===s}catch{}return i}reset(){this.cached=[],this.initialized=!0}onDisable(){this.values.length>0&&(this.cached=this.values),this.subscriptions.clear(),this.topicMap.clear()}async unsubscribeByTopic(t,s){const i=this.topicMap.get(t);await Promise.all(i.map(async e=>await this.unsubscribeById(t,e,s)))}async unsubscribeById(t,s,i){this.logger.debug("Unsubscribing Topic"),this.logger.trace({type:"method",method:"unsubscribe",params:{topic:t,id:s,opts:i}});try{const e=F("USER_DISCONNECTED",`${this.name}, ${t}`);await this.onUnsubscribe(t,s,e);const r=Z(i);await this.restartToComplete({topic:t,id:s,relay:r}),await this.rpcUnsubscribe(t,s,r),this.logger.debug("Successfully Unsubscribed Topic"),this.logger.trace({type:"method",method:"unsubscribe",params:{topic:t,id:s,opts:i}})}catch(e){throw this.logger.debug("Failed to Unsubscribe Topic"),this.logger.error(e),e}}async rpcSubscribe(t,s,i){const e=await this.getSubscriptionId(t);if(i?.internal?.skipSubscribe)return e;(!i||i?.transportType===D.relay)&&await this.restartToComplete({topic:t,id:t,relay:s});const r={method:$(s.protocol).subscribe,params:{topic:t}};this.logger.debug("Outgoing Relay Payload"),this.logger.trace({type:"payload",direction:"outgoing",request:r});const o=i?.internal?.throwOnFailedPublish;try{if(i?.transportType===D.link_mode)return setTimeout(()=>{(this.relayer.connected||this.relayer.connecting)&&this.relayer.request(r).catch(h=>this.logger.warn(h))},y(A)),e;const n=new Promise(async h=>{const d=l=>{l.topic===t&&(this.events.removeListener(b.created,d),h(l.id))};this.events.on(b.created,d);try{const l=await R(new Promise((g,_)=>{this.relayer.request(r).catch(E=>{this.logger.warn(E,E?.message),_(E)}).then(g)}),this.initialSubscribeTimeout,`Subscribing to ${t} failed, please try again`);this.events.removeListener(b.created,d),h(l)}catch{}}),a=await R(n,this.subscribeTimeout,`Subscribing to ${t} failed, please try again`);if(!a&&o)throw new Error(`Subscribing to ${t} failed, please try again`);return a?e:null}catch(n){if(this.logger.debug("Outgoing Relay Subscribe Payload stalled"),this.relayer.events.emit(p.connection_stalled),o)throw n}return null}async rpcBatchSubscribe(t){if(!t.length)return!0;const s=t[0].relay,i={method:$(s.protocol).batchSubscribe,params:{topics:t.map(e=>e.topic)}};this.logger.debug("Outgoing Relay Payload"),this.logger.trace({type:"payload",direction:"outgoing",request:i});try{return await R(new Promise((e,r)=>{this.relayer.request(i).then(e).catch(o=>{this.logger.warn(o),r(o)})}),this.subscribeTimeout,"rpcBatchSubscribe failed, please try again"),!0}catch{return this.relayer.events.emit(p.connection_stalled),!1}}async rpcBatchFetchMessages(t){if(!t.length)return;const s=t[0].relay,i={method:$(s.protocol).batchFetchMessages,params:{topics:t.map(r=>r.topic)}};this.logger.debug("Outgoing Relay Payload"),this.logger.trace({type:"payload",direction:"outgoing",request:i});let e;try{e=await await R(new Promise((r,o)=>{this.relayer.request(i).catch(n=>{this.logger.warn(n),o(n)}).then(r)}),this.subscribeTimeout,"rpcBatchFetchMessages failed, please try again")}catch{this.relayer.events.emit(p.connection_stalled)}return e}rpcUnsubscribe(t,s,i){const e={method:$(i.protocol).unsubscribe,params:{topic:t,id:s}};return this.logger.debug("Outgoing Relay Payload"),this.logger.trace({type:"payload",direction:"outgoing",request:e}),this.relayer.request(e)}onSubscribe(t,s){this.setSubscription(t,{...s,id:t}),this.pending.delete(s.topic)}onBatchSubscribe(t){t.length&&t.forEach(s=>{this.setSubscription(s.id,{...s}),this.pending.delete(s.topic)})}async onUnsubscribe(t,s,i){this.events.removeAllListeners(s),this.hasSubscription(s,t)&&this.deleteSubscription(s,i),await this.relayer.messages.del(t)}async setRelayerSubscriptions(t){await this.relayer.core.storage.setItem(this.storageKey,t)}async getRelayerSubscriptions(){return await this.relayer.core.storage.getItem(this.storageKey)}setSubscription(t,s){this.logger.debug("Setting subscription"),this.logger.trace({type:"method",method:"setSubscription",id:t,subscription:s}),this.addSubscription(t,s)}addSubscription(t,s){this.subscriptions.set(t,{...s}),this.topicMap.set(s.topic,t),this.events.emit(b.created,s)}getSubscription(t){this.logger.debug("Getting subscription"),this.logger.trace({type:"method",method:"getSubscription",id:t});const s=this.subscriptions.get(t);if(!s){const{message:i}=c("NO_MATCHING_KEY",`${this.name}: ${t}`);throw new Error(i)}return s}deleteSubscription(t,s){this.logger.debug("Deleting subscription"),this.logger.trace({type:"method",method:"deleteSubscription",id:t,reason:s});const i=this.getSubscription(t);this.subscriptions.delete(t),this.topicMap.delete(i.topic,t),this.events.emit(b.deleted,{...i,reason:s})}async persist(){await this.setRelayerSubscriptions(this.values),this.events.emit(b.sync)}async onRestart(){if(this.cached.length){const t=[...this.cached],s=Math.ceil(this.cached.length/this.batchSubscribeTopicsLimit);for(let i=0;i<s;i++){const e=t.splice(0,this.batchSubscribeTopicsLimit);await this.batchSubscribe(e)}}this.events.emit(b.resubscribed)}async restore(){try{const t=await this.getRelayerSubscriptions();if(typeof t>"u"||!t.length)return;if(this.subscriptions.size&&!t.every(s=>s.topic===this.subscriptions.get(s.id)?.topic)){const{message:s}=c("RESTORE_WILL_OVERRIDE",this.name);throw this.logger.error(s),this.logger.error(`${this.name}: ${JSON.stringify(this.values)}`),new Error(s)}this.cached=t,this.logger.debug(`Successfully Restored subscriptions for ${this.name}`),this.logger.trace({type:"method",method:"restore",subscriptions:this.values})}catch(t){this.logger.debug(`Failed to Restore subscriptions for ${this.name}`),this.logger.error(t)}}async batchSubscribe(t){if(t.length){if(!await this.rpcBatchSubscribe(t)){this.logger.warn(`Batch subscribe failed for ${t.length} topics, adding to pending for retry`),t.forEach(s=>{this.pending.set(s.topic,s)});return}this.onBatchSubscribe(await Promise.all(t.map(async s=>({...s,id:await this.getSubscriptionId(s.topic)}))))}}async batchFetchMessages(t){if(!t.length)return;this.logger.trace(`Fetching batch messages for ${t.length} subscriptions`);const s=await this.rpcBatchFetchMessages(t);s&&s.messages&&(await hi(y(A)),await this.relayer.handleBatchMessageEvents(s.messages))}async onConnect(){await this.restart(),this.reset()}onDisconnect(){this.onDisable()}isInitialized(){if(!this.initialized){const{message:t}=c("NOT_INITIALIZED",this.name);throw new Error(t)}}async restartToComplete(t){!this.relayer.connected&&!this.relayer.connecting&&(this.cached.push(t),await this.relayer.transportOpen())}async getClientId(){return this.clientId||(this.clientId=await this.relayer.core.crypto.getClientId()),this.clientId}async getSubscriptionId(t){return X(t+await this.getClientId())}}class fe extends Ue{constructor(t){super(t),this.protocol="wc",this.version=2,this.events=new z,this.name=Ht,this.transportExplicitlyClosed=!1,this.initialized=!1,this.connectionAttemptInProgress=!1,this.hasExperiencedNetworkDisruption=!1,this.heartBeatTimeout=y(J+it),this.reconnectInProgress=!1,this.requestsInFlight=[],this.connectTimeout=y(A*15),this.stalledRestartInProgress=!1,this.stalledRestartBackoff=0,this.stalledRestartBaseInterval=y(A*2),this.stalledRestartMaxInterval=y(J),this.request=async s=>{this.logger.debug("Publishing Request Payload");const i=s.id||ht().toString();await this.toEstablishConnection();try{this.logger.trace({id:i,method:s.method,topic:s.params?.topic},"relayer.request - publishing...");const e=`${i}:${s.params?.tag||""}`;this.requestsInFlight.push(e);const r=await this.provider.request(s);return this.requestsInFlight=this.requestsInFlight.filter(o=>o!==e),r}catch(e){throw this.logger.debug(`Failed to Publish Request: ${i}`),e}},this.resetPingTimeout=()=>{Et()&&(clearTimeout(this.pingTimeout),this.pingTimeout=setTimeout(()=>{try{this.logger.debug({},"pingTimeout: Connection stalled, terminating..."),this.provider?.connection?.socket?.terminate?.()}catch(s){this.logger.warn(s,s?.message)}},this.heartBeatTimeout))},this.onPayloadHandler=s=>{this.onProviderPayload(s),this.resetPingTimeout()},this.onConnectHandler=()=>{this.logger.warn({},"Relayer connected \u{1F6DC}"),this.startPingTimeout(),this.stalledRestartBackoff=0,this.events.emit(p.connect)},this.onDisconnectHandler=()=>{this.logger.warn({},"Relayer disconnected \u{1F6D1}"),this.requestsInFlight=[],this.onProviderDisconnect()},this.onProviderErrorHandler=s=>{this.logger.fatal(`Fatal socket error: ${s.message}`),this.events.emit(p.error,s),this.logger.fatal("Fatal socket error received, closing transport"),this.transportExplicitlyClosed=!0,clearTimeout(this.reconnectTimeout),this.reconnectTimeout=void 0,this.reconnectInProgress=!1,this.transportClose().catch(i=>this.logger.warn(i))},this.registerProviderListeners=()=>{this.provider.on(v.payload,this.onPayloadHandler),this.provider.on(v.connect,this.onConnectHandler),this.provider.on(v.disconnect,this.onDisconnectHandler),this.provider.on(v.error,this.onProviderErrorHandler)},this.core=t.core,this.logger=ci({logger:t.logger??Wt,name:this.name}),this.messages=new be(this.logger,t.core),this.subscriber=new we(this,this.logger),this.publisher=new Hi(this,this.logger),this.projectId=t.projectId,this.relayUrl=t.relayUrl||pt,li()?this.packageName=It():gi()&&(this.bundleId=It()),this.provider={}}async init(){this.logger.trace("Initialized"),this.registerEventListeners(),await Promise.all([this.messages.init(),this.subscriber.init()]),this.initialized=!0,this.transportOpen().catch(t=>this.logger.warn(t,t?.message))}get context(){return I(this.logger)}get connected(){return this.provider?.connection?.socket?.readyState===1}get connecting(){return this.provider?.connection?.socket?.readyState===0||this.connectPromise!==void 0}async publish(t,s,i){this.isInitialized(),await this.publisher.publish(t,s,i),await this.recordMessageEvent({topic:t,message:s,publishedAt:Date.now(),transportType:D.relay},H.outbound)}async publishCustom(t){this.isInitialized(),await this.publisher.publishCustom(t)}async subscribe(t,s){this.isInitialized(),(!s?.transportType||s?.transportType==="relay")&&await this.toEstablishConnection();const i=s?.internal?.throwOnFailedPublish??!0;let e=this.subscriber.topicMap.get(t)?.[0]||"",r;const o=n=>{n.topic===t&&(this.subscriber.off(b.created,o),r())};return await Promise.all([new Promise(n=>{r=n,this.subscriber.on(b.created,o)}),new Promise((n,a)=>{this.subscriber.subscribe(t,{internal:{throwOnFailedPublish:i},...s}).then(h=>{e=h||e,n()}).catch(h=>{i?a(h):n()})})]),e}async unsubscribe(t,s){this.isInitialized(),await this.subscriber.unsubscribe(t,s)}on(t,s){this.events.on(t,s)}once(t,s){this.events.once(t,s)}off(t,s){this.events.off(t,s)}removeListener(t,s){this.events.removeListener(t,s)}async transportDisconnect(){this.provider.disconnect&&(this.hasExperiencedNetworkDisruption||this.connected)?await R(this.provider.disconnect(),2e3,"provider.disconnect()").catch(()=>this.onProviderDisconnect()):this.onProviderDisconnect()}async transportClose(){this.transportExplicitlyClosed=!0,clearTimeout(this.stalledRestartTimeout),this.stalledRestartInProgress=!1,this.stalledRestartBackoff=0,await this.resetTransport()}async transportOpen(t){if(!this.subscriber.hasAnyTopics){this.logger.info("Starting WS connection skipped because the client has no topics to work with.");return}if(this.connectPromise?(this.logger.debug({},"Waiting for existing connection attempt to resolve..."),await this.connectPromise,this.logger.debug({},"Existing connection attempt resolved")):(this.connectPromise=this.connect(t).finally(()=>{this.connectPromise=void 0}),await this.connectPromise),!this.connected)throw new Error(`Couldn't establish socket connection to the relay server: ${this.relayUrl}`)}async restartTransport(t){this.logger.debug({},"Restarting transport..."),!this.connectionAttemptInProgress&&(this.relayUrl=t||this.relayUrl,await this.confirmOnlineStateOrThrow(),await this.resetTransport(),await this.transportOpen())}async resetTransport(){this.reconnectInProgress=!0,clearTimeout(this.reconnectTimeout),this.reconnectTimeout=void 0,await this.transportDisconnect(),await this.subscriber.stop(),this.reconnectInProgress=!1}async confirmOnlineStateOrThrow(){if(!await Tt())throw new Error("No internet connection detected. Please restart your network and try again.")}async handleBatchMessageEvents(t){if(t?.length===0){this.logger.trace("Batch message events is empty. Ignoring...");return}const s=t.sort((i,e)=>i.publishedAt-e.publishedAt);this.logger.debug(`Batch of ${s.length} message events sorted`);for(const i of s)try{await this.onMessageEvent(i)}catch(e){this.logger.warn(e,"Error while processing batch message event: "+e?.message)}this.logger.trace(`Batch of ${s.length} message events processed`)}async onLinkMessageEvent(t,s){const{topic:i}=t;if(!s.sessionExists){const e=G(V),r={topic:i,expiry:e,relay:{protocol:"irn"},active:!1};await this.core.pairing.pairings.set(i,r)}this.events.emit(p.message,t),await this.recordMessageEvent(t,H.inbound)}async connect(t){await this.confirmOnlineStateOrThrow(),t&&t!==this.relayUrl&&(this.relayUrl=t,await this.transportDisconnect()),this.transportExplicitlyClosed=!1;let s=1;try{for(;s<6;){this.connectionAttemptInProgress=!0;try{if(this.transportExplicitlyClosed)break;this.logger.debug({},`Connecting to ${this.relayUrl}, attempt: ${s}...`),await this.createProvider(),await new Promise((i,e)=>{const r=()=>{e(new Error("Connection interrupted while trying to connect"))};this.provider.once(v.disconnect,r),R(this.provider.connect(),this.connectTimeout,`Socket stalled when trying to connect to ${this.relayUrl}`).then(()=>i()).catch(e).finally(()=>{this.provider.off(v.disconnect,r),clearTimeout(this.reconnectTimeout)})}),await new Promise((i,e)=>{const r=()=>{e(new Error("Connection interrupted while trying to subscribe"))};this.provider.once(v.disconnect,r),this.subscriber.start().then(i).catch(e).finally(()=>{this.provider.off(v.disconnect,r)})}),this.hasExperiencedNetworkDisruption=!1}catch(i){await this.subscriber.stop();const e=i;this.logger.warn({},e.message),this.hasExperiencedNetworkDisruption=!0}if(this.connected){this.logger.debug({},`Connected to ${this.relayUrl} successfully on attempt: ${s}`);break}await new Promise(i=>setTimeout(i,y(s*1))),s++}}finally{this.connectionAttemptInProgress=!1,clearTimeout(this.reconnectTimeout),this.reconnectTimeout=void 0,this.reconnectInProgress=!1}}startPingTimeout(){if(Et())try{this.provider?.connection?.socket?.on("ping",()=>{this.resetPingTimeout()}),this.resetPingTimeout()}catch(t){this.logger.warn(t,t?.message)}}async createProvider(){if(this.provider.connection&&(this.unregisterProviderListeners(),this.connected))try{await R(this.provider.disconnect(),1e3,"Closing previous provider")}catch{}const t=await this.core.crypto.signJWT(this.relayUrl);this.provider=new xi(new Ni(pi({sdkVersion:Q,protocol:this.protocol,version:this.version,relayUrl:this.relayUrl,projectId:this.projectId,auth:t,useOnCloseEvent:!0,bundleId:this.bundleId,packageName:this.packageName}))),this.registerProviderListeners()}async recordMessageEvent(t,s){const{topic:i,message:e}=t;await this.messages.set(i,e,s)}async shouldIgnoreMessageEvent(t){const{topic:s,message:i}=t;if(!i||i.length===0)return this.logger.warn(`Ignoring invalid/empty message: ${i}`),!0;if(!await this.subscriber.isKnownTopic(s))return this.logger.warn(`Ignoring message for unknown topic ${s}`),!0;const e=this.messages.has(s,i);return e&&this.logger.warn(`Ignoring duplicate message: ${i}`),e}async onProviderPayload(t){if(this.logger.debug("Incoming Relay Payload"),this.logger.trace({type:"payload",direction:"incoming",payload:t}),Ot(t)){if(!t.method.endsWith(Yt))return;const s=t.params,{topic:i,message:e,publishedAt:r,attestation:o}=s.data,n={topic:i,message:e,publishedAt:r,transportType:D.relay,attestation:o};this.logger.debug("Emitting Relayer Payload"),this.logger.trace({type:"event",event:s.id,...n}),this.events.emit(s.id,n),await this.acknowledgePayload(t),await this.onMessageEvent(n)}else At(t)&&this.events.emit(p.message_ack,t)}async onMessageEvent(t){await this.shouldIgnoreMessageEvent(t)||(await this.recordMessageEvent(t,H.inbound),this.events.emit(p.message,t))}async acknowledgePayload(t){const s=Nt(t.id,!0);await this.provider.connection.send(s)}unregisterProviderListeners(){this.provider.off(v.payload,this.onPayloadHandler),this.provider.off(v.connect,this.onConnectHandler),this.provider.off(v.disconnect,this.onDisconnectHandler),this.provider.off(v.error,this.onProviderErrorHandler),clearTimeout(this.pingTimeout)}async registerEventListeners(){let t=await Tt();di(async s=>{t!==s&&(t=s,s?await this.transportOpen().catch(i=>this.logger.error(i,i?.message)):(this.hasExperiencedNetworkDisruption=!0,await this.transportDisconnect(),this.transportExplicitlyClosed=!1))}),this.core.heartbeat.on(K.pulse,async()=>{if(!this.transportExplicitlyClosed&&!this.connected&&ui())try{await this.confirmOnlineStateOrThrow(),await this.transportOpen()}catch(s){this.logger.warn(s,s?.message)}}),this.events.on(p.connection_stalled,()=>{if(this.transportExplicitlyClosed||this.stalledRestartInProgress)return;this.stalledRestartInProgress=!0;const s=this.stalledRestartBackoff===0?0:Math.min(Math.pow(2,this.stalledRestartBackoff-1)*this.stalledRestartBaseInterval,this.stalledRestartMaxInterval);this.stalledRestartBackoff++,this.logger.warn(`Connection stalled, restarting transport${s?` in ${s}ms`:""}...`),this.stalledRestartTimeout=setTimeout(async()=>{try{if(this.transportExplicitlyClosed)return;await this.restartTransport()}catch(i){this.logger.error(i,i?.message)}finally{this.stalledRestartInProgress=!1}},s)})}async onProviderDisconnect(){if(clearTimeout(this.pingTimeout),this.events.emit(p.disconnect),!this.reconnectInProgress){this.reconnectInProgress=!0;try{await this.subscriber.stop()}catch(t){this.logger.warn(t,"subscriber.stop() failed during disconnect")}if(!this.subscriber.hasAnyTopics||this.transportExplicitlyClosed){this.reconnectInProgress=!1;return}this.reconnectTimeout=setTimeout(async()=>{await this.transportOpen().catch(t=>this.logger.error(t,t?.message)),this.reconnectTimeout=void 0,this.reconnectInProgress=!1},y(Jt))}}isInitialized(){if(!this.initialized){const{message:t}=c("NOT_INITIALIZED",this.name);throw new Error(t)}}async toEstablishConnection(){if(await this.confirmOnlineStateOrThrow(),!this.connected){if(this.connectPromise){await this.connectPromise;return}this.connectPromise=this.connect().finally(()=>{this.connectPromise=void 0}),await this.connectPromise}}}class ve extends qe{constructor(t,s,i,e=S,r=void 0){super(t,s,i,e),this.core=t,this.logger=s,this.name=i,this.map=new Map,this.version=jt,this.cached=[],this.initialized=!1,this.storagePrefix=S,this.recentlyDeleted=[],this.recentlyDeletedLimit=200,this.init=async()=>{this.initialized||(this.logger.trace("Initialized"),await this.restore(),this.cached.forEach(o=>{this.getKey&&o!==null&&!B(o)?this.map.set(this.getKey(o),o):yi(o)?this.map.set(o.id,o):mi(o)&&this.map.set(o.topic,o)}),this.cached=[],this.initialized=!0)},this.set=async(o,n)=>{this.isInitialized(),this.map.has(o)?await this.update(o,n):(this.logger.debug("Setting value"),this.logger.trace({type:"method",method:"set",key:o,value:n}),this.map.set(o,n),await this.persist())},this.get=o=>(this.isInitialized(),this.logger.debug("Getting value"),this.logger.trace({type:"method",method:"get",key:o}),this.getData(o)),this.getAll=o=>(this.isInitialized(),o?this.values.filter(n=>Object.keys(o).every(a=>ki(n[a],o[a]))):this.values),this.update=async(o,n)=>{this.isInitialized(),this.logger.debug("Updating value"),this.logger.trace({type:"method",method:"update",key:o,update:n});const a={...this.getData(o),...n};this.map.set(o,a),await this.persist()},this.delete=async(o,n)=>{this.isInitialized(),this.map.has(o)&&(this.logger.debug("Deleting value"),this.logger.trace({type:"method",method:"delete",key:o,reason:n}),this.map.delete(o),this.addToRecentlyDeleted(o),await this.persist())},this.logger=f(s,this.name),this.storagePrefix=e,this.getKey=r}get context(){return I(this.logger)}get storageKey(){return this.storagePrefix+this.version+this.core.customStoragePrefix+"//"+this.name}get length(){return this.map.size}get keys(){return Array.from(this.map.keys())}get values(){return Array.from(this.map.values())}addToRecentlyDeleted(t){this.recentlyDeleted.push(t),this.recentlyDeleted.length>=this.recentlyDeletedLimit&&this.recentlyDeleted.splice(0,this.recentlyDeletedLimit/2)}async setDataStore(t){await this.core.storage.setItem(this.storageKey,t)}async getDataStore(){return await this.core.storage.getItem(this.storageKey)}getData(t){const s=this.map.get(t);if(!s){if(this.recentlyDeleted.includes(t)){const{message:e}=c("MISSING_OR_INVALID",`Record was recently deleted - ${this.name}: ${t}`);throw this.logger.error(e),new Error(e)}const{message:i}=c("NO_MATCHING_KEY",`${this.name}: ${t}`);throw this.logger.error(i),new Error(i)}return s}async persist(){await this.setDataStore(this.values)}async restore(){try{const t=await this.getDataStore();if(typeof t>"u"||!t.length)return;if(this.map.size){const{message:s}=c("RESTORE_WILL_OVERRIDE",this.name);throw this.logger.error(s),new Error(s)}this.cached=t,this.logger.debug(`Successfully Restored value for ${this.name}`),this.logger.trace({type:"method",method:"restore",value:this.values})}catch(t){this.logger.debug(`Failed to Restore value for ${this.name}`),this.logger.error(t)}}isInitialized(){if(!this.initialized){const{message:t}=c("NOT_INITIALIZED",this.name);throw new Error(t)}}}class Ee{constructor(t,s){this.core=t,this.logger=s,this.name=te,this.version=ee,this.events=new Ne,this.initialized=!1,this.storagePrefix=S,this.ignoredPayloadTypes=[_i],this.registeredMethods=[],this.init=async()=>{this.initialized||(await this.pairings.init(),await this.cleanup(),this.registerRelayerEvents(),this.registerExpirerEvents(),this.initialized=!0,this.logger.trace("Initialized"))},this.register=({methods:i})=>{this.isInitialized(),this.registeredMethods=[...new Set([...this.registeredMethods,...i])]},this.create=async i=>{this.isInitialized();const e=ot(),r=await this.core.crypto.setSymKey(e),o=G(V),n={protocol:Gt},a={topic:r,expiry:o,relay:n,active:!1,methods:i?.methods},h=Pt({protocol:this.core.protocol,version:this.core.version,topic:r,symKey:e,relay:n,expiryTimestamp:o,methods:i?.methods});return this.events.emit(q.create,a),this.core.expirer.set(r,o),await this.pairings.set(r,a),await this.core.relayer.subscribe(r,{transportType:i?.transportType,internal:i?.internal}),{topic:r,uri:h}},this.pair=async i=>{this.isInitialized();const e=this.core.eventClient.createEvent({properties:{topic:i?.uri,trace:[x.pairing_started]}});this.isValidPair(i,e);const{topic:r,symKey:o,relay:n,expiryTimestamp:a,methods:h}=Rt(i.uri);e.props.properties.topic=r,e.addTrace(x.pairing_uri_validation_success),e.addTrace(x.pairing_uri_not_expired);let d;if(this.pairings.keys.includes(r)){if(d=this.pairings.get(r),e.addTrace(x.existing_pairing),d.active)throw e.setError(O.active_pairing_already_exists),new Error(`Pairing already exists: ${r}. Please try again with a new connection URI.`);e.addTrace(x.pairing_not_expired)}const l=a||G(V),g={topic:r,relay:n,expiry:l,active:!1,methods:h};this.core.expirer.set(r,l),await this.pairings.set(r,g),e.addTrace(x.store_new_pairing),i.activatePairing&&await this.activate({topic:r}),this.events.emit(q.create,g),e.addTrace(x.emit_inactive_pairing),this.core.crypto.keychain.has(r)||await this.core.crypto.setSymKey(o,r),e.addTrace(x.subscribing_pairing_topic);try{await this.core.relayer.confirmOnlineStateOrThrow()}catch{e.setError(O.no_internet_connection)}try{await this.core.relayer.subscribe(r,{relay:n})}catch(_){throw e.setError(O.subscribe_pairing_topic_failure),_}return e.addTrace(x.subscribe_pairing_topic_success),g},this.activate=async({topic:i})=>{this.isInitialized();const e=G(V);this.core.expirer.set(i,e),await this.pairings.update(i,{active:!0,expiry:e})},this.ping=async i=>{this.isInitialized(),await this.isValidPing(i),this.logger.warn("ping() is deprecated and will be removed in the next major release.");const{topic:e}=i;if(this.pairings.keys.includes(e)){const r=await this.sendRequest(e,"wc_pairingPing",{}),{done:o,resolve:n,reject:a}=bi();this.events.once(nt("pairing_ping",r),({error:h})=>{h?a(h):n()}),await o()}},this.updateExpiry=async({topic:i,expiry:e})=>{this.isInitialized(),await this.pairings.update(i,{expiry:e})},this.updateMetadata=async({topic:i,metadata:e})=>{this.isInitialized(),await this.pairings.update(i,{peerMetadata:e})},this.getPairings=()=>(this.isInitialized(),this.pairings.values),this.disconnect=async i=>{this.isInitialized(),await this.isValidDisconnect(i);const{topic:e}=i;this.pairings.keys.includes(e)&&(await this.sendRequest(e,"wc_pairingDelete",F("USER_DISCONNECTED")),await this.deletePairing(e))},this.formatUriFromPairing=i=>{this.isInitialized();const{topic:e,relay:r,expiry:o,methods:n}=i,a=this.core.crypto.keychain.get(e);return Pt({protocol:this.core.protocol,version:this.core.version,topic:e,symKey:a,relay:r,expiryTimestamp:o,methods:n})},this.sendRequest=async(i,e,r)=>{const o=kt(e,r),n=await this.core.crypto.encode(i,o),a=U[e].req;return this.core.history.set(i,o),this.core.relayer.publish(i,n,a),o.id},this.sendResult=async(i,e,r)=>{const o=Nt(i,r),n=await this.core.crypto.encode(e,o),a=(await this.core.history.get(e,i)).request.method,h=U[a].res;await this.core.relayer.publish(e,n,h),await this.core.history.resolve(o)},this.sendError=async(i,e,r)=>{const o=Oi(i,r),n=await this.core.crypto.encode(e,o),a=(await this.core.history.get(e,i)).request.method,h=U[a]?U[a].res:U.unregistered_method.res;await this.core.relayer.publish(e,n,h),await this.core.history.resolve(o)},this.deletePairing=async(i,e)=>{await this.core.relayer.unsubscribe(i),await Promise.all([this.pairings.delete(i,F("USER_DISCONNECTED")),this.core.crypto.deleteSymKey(i),e?Promise.resolve():this.core.expirer.del(i)])},this.cleanup=async()=>{const i=this.pairings.getAll().filter(e=>St(e.expiry));await Promise.all(i.map(e=>this.deletePairing(e.topic)))},this.onRelayEventRequest=async i=>{const{topic:e,payload:r}=i;switch(r.method){case"wc_pairingPing":return await this.onPairingPingRequest(e,r);case"wc_pairingDelete":return await this.onPairingDeleteRequest(e,r);default:return await this.onUnknownRpcMethodRequest(e,r)}},this.onRelayEventResponse=async i=>{const{topic:e,payload:r}=i,o=(await this.core.history.get(e,r.id)).request.method;switch(o){case"wc_pairingPing":return this.onPairingPingResponse(e,r);default:return this.onUnknownRpcMethodResponse(o)}},this.onPairingPingRequest=async(i,e)=>{const{id:r}=e;try{this.isValidPing({topic:i}),await this.sendResult(r,i,!0),this.events.emit(q.ping,{id:r,topic:i})}catch(o){await this.sendError(r,i,o),this.logger.error(o)}},this.onPairingPingResponse=(i,e)=>{const{id:r}=e;setTimeout(()=>{Ai(e)?this.events.emit(nt("pairing_ping",r),{}):Lt(e)&&this.events.emit(nt("pairing_ping",r),{error:e.error})},500)},this.onPairingDeleteRequest=async(i,e)=>{const{id:r}=e;try{this.isValidDisconnect({topic:i}),await this.deletePairing(i),this.events.emit(q.delete,{id:r,topic:i})}catch(o){await this.sendError(r,i,o),this.logger.error(o)}},this.onUnknownRpcMethod