UNPKG

@walletconnect/sign-client

Version:
1 lines 67.9 kB
import mt,{EventEmitter as _t}from"events";import{RELAYER_DEFAULT_PROTOCOL as ft,EVENT_CLIENT_SESSION_TRACES as C,EVENT_CLIENT_SESSION_ERRORS as Y,TRANSPORT_TYPES as I,EVENT_CLIENT_AUTHENTICATE_TRACES as X,EVENT_CLIENT_AUTHENTICATE_ERRORS as pe,EVENT_CLIENT_PAIRING_ERRORS as St,EVENT_CLIENT_PAIRING_TRACES as Et,VERIFY_SERVER as Rt,RELAYER_EVENTS as It,EXPIRER_EVENTS as Tt,PAIRING_EVENTS as De,Store as se,Core as qt}from"@walletconnect/core";import{IEngine as vt,ISignClient as Pt}from"@walletconnect/types";import{LimitedSet as Nt,mergeRequiredAndOptionalNamespaces as Ot,getInternalError as d,calcExpiry as N,engineEvent as f,createDelayedPromise as ie,getSdkError as D,getDeepLink as bt,handleDeeplinkRedirect as At,isSessionCompatible as xt,hashKey as qe,parseChainId as ve,createEncodedRecap as Ct,getRecapFromResources as Pe,mergeEncodedRecaps as kt,BASE64URL as he,TYPE_2 as Vt,getLinkModeURL as we,validateSignedCacao as Me,TYPE_1 as Ne,getNamespacedDidChainId as $e,getDidAddress as Ke,getMethodsFromRecap as Ue,getChainsFromRecap as Ge,buildNamespacesFromAuth as Fe,formatMessage as Lt,BASE64 as J,hashMessage as G,isExpired as re,MemoryStore as de,isValidParams as k,isUndefined as B,isValidRelays as Dt,isValidObject as je,isValidRequiredNamespaces as Mt,isValidNamespaces as Oe,isConformingNamespaces as Qe,isValidString as W,isValidErrorReason as $t,isValidRelay as Kt,isValidController as Ut,isValidNamespacesChainId as He,isValidRequest as Gt,isValidNamespacesRequest as Ft,isValidResponse as jt,isValidEvent as Qt,isValidNamespacesEvent as Ht,getSearchParamFromURL as ze,isTestRun as zt,isReactNative as Yt,getNamespacesChains as Xt,getNamespacesMethods as Jt,getNamespacesEvents as Bt,getSuiDigest as Wt,getNearTransactionIdFromSignedTransaction as Ye,buildSignedExtrinsicHash as Zt,isValidArray as Xe,getAlgorandTransactionId as Je,getSignDirectHash as es,getWalletSendCallsHashes as ts,extractSolanaTransactionId as ss,parseExpirerTarget as is,isValidId as rs,isValidRequestExpiry as ns,populateAppMetadata as os,createLogger as as}from"@walletconnect/utils";import{getLoggerContext as cs}from"@walletconnect/logger";import{THIRTY_DAYS as ls,SEVEN_DAYS as Be,FIVE_MINUTES as v,ONE_HOUR as We,ONE_DAY as F,ONE_SECOND as ps,toMiliseconds as Ze}from"@walletconnect/time";import{payloadId as j,getBigIntRpcId as me,isJsonRpcResult as Q,isJsonRpcError as H,formatJsonRpcRequest as ne,formatJsonRpcResult as et,formatJsonRpcError as hs,isJsonRpcRequest as ds,isJsonRpcResponse as us}from"@walletconnect/jsonrpc-utils";const be="wc",Ae=2,xe="client",_e=`${be}@${Ae}:${xe}:`,fe={name:xe,logger:"error",controller:!1,relayUrl:"wss://relay.walletconnect.org"},gs={session_proposal:"session_proposal",session_update:"session_update",session_extend:"session_extend",session_ping:"session_ping",session_delete:"session_delete",session_expire:"session_expire",session_request:"session_request",session_request_sent:"session_request_sent",session_event:"session_event",proposal_expire:"proposal_expire",session_authenticate:"session_authenticate",session_request_expire:"session_request_expire",session_connect:"session_connect"},ys={database:":memory:"},Ce="WALLETCONNECT_DEEPLINK_CHOICE",ws={created:"history_created",updated:"history_updated",deleted:"history_deleted",sync:"history_sync"},ms="history",_s="0.3",tt="proposal",fs=ls,ke="Proposal expired",st="session",Z=Be,it="engine",T={wc_sessionPropose:{req:{ttl:v,prompt:!0,tag:1100},res:{ttl:v,prompt:!1,tag:1101},reject:{ttl:v,prompt:!1,tag:1120},autoReject:{ttl:v,prompt:!1,tag:1121}},wc_sessionSettle:{req:{ttl:v,prompt:!1,tag:1102},res:{ttl:v,prompt:!1,tag:1103}},wc_sessionUpdate:{req:{ttl:F,prompt:!1,tag:1104},res:{ttl:F,prompt:!1,tag:1105}},wc_sessionExtend:{req:{ttl:F,prompt:!1,tag:1106},res:{ttl:F,prompt:!1,tag:1107}},wc_sessionRequest:{req:{ttl:v*3,prompt:!0,tag:1108},res:{ttl:v*3,prompt:!1,tag:1109}},wc_sessionEvent:{req:{ttl:v,prompt:!0,tag:1110},res:{ttl:v,prompt:!1,tag:1111}},wc_sessionDelete:{req:{ttl:F,prompt:!1,tag:1112},res:{ttl:F,prompt:!1,tag:1113}},wc_sessionPing:{req:{ttl:F,prompt:!1,tag:1114},res:{ttl:F,prompt:!1,tag:1115}},wc_sessionAuthenticate:{req:{ttl:We,prompt:!0,tag:1116},res:{ttl:We,prompt:!1,tag:1117},reject:{ttl:v,prompt:!1,tag:1118},autoReject:{ttl:v,prompt:!1,tag:1119}}},Se={min:v,max:Be},V={idle:"IDLE",active:"ACTIVE"},rt={eth_sendTransaction:{key:""},eth_sendRawTransaction:{key:""},wallet_sendCalls:{key:""},solana_signTransaction:{key:"signature"},solana_signAllTransactions:{key:"transactions"},solana_signAndSendTransaction:{key:"signature"},sui_signAndExecuteTransaction:{key:"digest"},sui_signTransaction:{key:""},hedera_signAndExecuteTransaction:{key:"transactionId"},hedera_executeTransaction:{key:"transactionId"},near_signTransaction:{key:""},near_signTransactions:{key:""},tron_signTransaction:{key:"txID"},xrpl_signTransaction:{key:""},xrpl_signTransactionFor:{key:""},algo_signTxn:{key:""},sendTransfer:{key:"txid"},stacks_stxTransfer:{key:"txId"},polkadot_signTransaction:{key:""},cosmos_signDirect:{key:""}},nt="request",ot=["wc_sessionPropose","wc_sessionRequest","wc_authRequest","wc_sessionAuthenticate"],at="wc",Ss=1.5,ct="auth",lt="authKeys",pt="pairingTopics",ht="requests",ue=`${at}@${1.5}:${ct}:`,$=`${ue}:PUB_KEY`;class Es extends vt{constructor(a){super(a),this.name=it,this.events=new mt,this.initialized=!1,this.requestQueue={state:V.idle,queue:[]},this.sessionRequestQueue={state:V.idle,queue:[]},this.emittedSessionRequests=new Nt({limit:500}),this.requestQueueDelay=ps,this.expectedPairingMethodMap=new Map,this.recentlyDeletedMap=new Map,this.recentlyDeletedLimit=200,this.relayMessageCache=[],this.pendingSessions=new Map,this.init=async()=>{this.initialized||(await this.cleanup(),this.registerRelayerEvents(),this.registerExpirerEvents(),this.registerPairingEvents(),this.registerSubscriptionCleanup(),await this.registerLinkModeListeners(),this.client.core.pairing.register({methods:Object.keys(T)}),this.initialized=!0,setTimeout(async()=>{await this.processPendingMessageEvents(),this.sessionRequestQueue.queue=this.getPendingSessionRequests(),this.processSessionRequestQueue()},Ze(this.requestQueueDelay)))},this.connect=async t=>{this.isInitialized(),await this.confirmOnlineStateOrThrow();const e={...t,requiredNamespaces:t.requiredNamespaces||{},optionalNamespaces:t.optionalNamespaces||{}};await this.isValidConnect(e),e.optionalNamespaces=Ot(e.requiredNamespaces,e.optionalNamespaces),e.requiredNamespaces={};const{pairingTopic:s,requiredNamespaces:i,optionalNamespaces:r,sessionProperties:n,scopedProperties:o,relays:c,authentication:l,walletPay:p}=e,g=l?.[0]?.ttl||T.wc_sessionPropose.req.ttl||v;this.validateRequestExpiry(g);let y=s,u,m=!1;try{if(y){const E=this.client.core.pairing.pairings.get(y);this.client.logger.warn("connect() with existing pairing topic is deprecated and will be removed in the next major release."),m=E.active}}catch(E){throw this.client.logger.error(`connect() -> pairing.get(${y}) failed`),E}if(!y||!m){const{topic:E,uri:A}=await this.client.core.pairing.create({internal:{skipSubscribe:!0}});y=E,u=A}if(!y){const{message:E}=d("NO_MATCHING_KEY",`connect() pairing topic: ${y}`);throw new Error(E)}const h=await this.client.core.crypto.generateKeyPair(),w=N(g),_={requiredNamespaces:i,optionalNamespaces:r,relays:c??[{protocol:ft}],proposer:{publicKey:h,metadata:this.client.metadata},expiryTimestamp:w,pairingTopic:y,...n&&{sessionProperties:n},...o&&{scopedProperties:o},id:j(),...(l||p)&&{requests:{authentication:l?.map(E=>{const{domain:A,chains:K,nonce:U,uri:M,exp:ee,nbf:oe,type:te,statement:ae,requestId:ge,resources:R,signatureTypes:q}=E;return{domain:A,chains:K,nonce:U,type:te??"caip122",aud:M,version:"1",iat:new Date().toISOString(),exp:ee,nbf:oe,statement:ae,requestId:ge,resources:R,signatureTypes:q}}),walletPay:p}}},S=f("session_connect",_.id),{reject:b,resolve:O,done:L}=ie(g,ke),P=({id:E})=>{if(E===_.id){this.client.events.off("proposal_expire",P);const A=this.pendingSessions.get(_.id);if(A){const{sessionTopic:K,publicKey:U}=A;Promise.all([this.client.core.relayer.unsubscribe(K),this.client.core.crypto.keychain.has(K)?this.client.core.crypto.deleteSymKey(K):Promise.resolve(),this.client.core.crypto.keychain.has(U)?this.client.core.crypto.deleteKeyPair(U):Promise.resolve()]).catch(M=>this.client.logger.warn(M))}this.pendingSessions.delete(_.id),this.events.emit(S,{error:{message:ke,code:0}})}};return this.client.events.on("proposal_expire",P),this.events.once(S,({error:E,session:A})=>{this.client.events.off("proposal_expire",P),E?b(E):A&&O(A)}),await this.setProposal(_.id,_),await this.sendProposeSession({proposal:_,publishOpts:{internal:{throwOnFailedPublish:!0},tvf:{correlationId:_.id}}}).catch(E=>{throw this.deleteProposal(_.id),E}),{uri:u,approval:L}},this.pair=async t=>{this.isInitialized(),await this.confirmOnlineStateOrThrow();try{return await this.client.core.pairing.pair(t)}catch(e){throw this.client.logger.error("pair() failed"),e}},this.approve=async t=>{const e=this.client.core.eventClient.createEvent({properties:{topic:t?.id?.toString(),trace:[C.session_approve_started]}});try{this.isInitialized(),await this.confirmOnlineStateOrThrow()}catch(P){throw e.setError(Y.no_internet_connection),P}try{await this.isValidProposalId(t?.id)}catch(P){throw this.client.logger.error(`approve() -> proposal.get(${t?.id}) failed`),e.setError(Y.proposal_not_found),P}try{await this.isValidApprove(t)}catch(P){throw this.client.logger.error("approve() -> isValidApprove() failed"),e.setError(Y.session_approve_namespace_validation_failure),P}const{id:s,relayProtocol:i,namespaces:r,sessionProperties:n,scopedProperties:o,sessionConfig:c,proposalRequestsResponses:l}=t,p=this.client.proposal.get(s);this.client.core.eventClient.deleteEvent({eventId:e.eventId});const{pairingTopic:g,proposer:y,requiredNamespaces:u,optionalNamespaces:m}=p;let h=this.client.core.eventClient?.getEvent({topic:g});h||(h=this.client.core.eventClient?.createEvent({type:C.session_approve_started,properties:{topic:g,trace:[C.session_approve_started,C.session_namespaces_validation_success]}}));const w=await this.client.core.crypto.generateKeyPair(),_=y.publicKey,S=await this.client.core.crypto.generateSharedKey(w,_),b={relay:{protocol:i??"irn"},namespaces:r,controller:{publicKey:w,metadata:this.client.metadata},expiry:N(Z),...n&&{sessionProperties:n},...o&&{scopedProperties:o},...c&&{sessionConfig:c},proposalRequestsResponses:l},O=I.relay;h.addTrace(C.subscribing_session_topic);try{await this.client.core.relayer.subscribe(S,{transportType:O,internal:{skipSubscribe:!0}})}catch(P){throw h.setError(Y.subscribe_session_topic_failure),P}h.addTrace(C.subscribe_session_topic_success);const L={...b,topic:S,requiredNamespaces:u,optionalNamespaces:m,pairingTopic:g,acknowledged:!1,self:b.controller,peer:{publicKey:y.publicKey,metadata:y.metadata},controller:w,transportType:I.relay,authentication:l?.authentication,walletPayResult:l?.walletPay};await this.client.session.set(S,L),h.addTrace(C.store_session);try{await this.sendApproveSession({sessionTopic:S,proposal:p,pairingProposalResponse:{relay:{protocol:i??"irn"},responderPublicKey:w},sessionSettleRequest:b,publishOpts:{internal:{throwOnFailedPublish:!0},tvf:{correlationId:s,...this.getTVFApproveParams(L)}}}),h.addTrace(C.session_approve_publish_success)}catch(P){throw this.client.logger.error(P),this.client.session.delete(S,D("USER_DISCONNECTED")),await this.client.core.relayer.unsubscribe(S),P}return this.client.core.eventClient.deleteEvent({eventId:h.eventId}),await this.client.core.pairing.updateMetadata({topic:g,metadata:y.metadata}),await this.deleteProposal(s),await this.client.core.pairing.activate({topic:g}),await this.setExpiry(S,N(Z)),{topic:S,acknowledged:()=>Promise.resolve(this.client.session.get(S))}},this.reject=async t=>{this.isInitialized(),await this.confirmOnlineStateOrThrow();try{await this.isValidReject(t)}catch(r){throw this.client.logger.error("reject() -> isValidReject() failed"),r}const{id:e,reason:s}=t;let i;try{i=this.client.proposal.get(e).pairingTopic}catch(r){throw this.client.logger.error(`reject() -> proposal.get(${e}) failed`),r}i&&await this.sendError({id:e,topic:i,error:s,rpcOpts:T.wc_sessionPropose.reject}),await this.deleteProposal(e)},this.update=async t=>{this.isInitialized(),await this.confirmOnlineStateOrThrow();try{await this.isValidUpdate(t)}catch(p){throw this.client.logger.error("update() -> isValidUpdate() failed"),p}const{topic:e,namespaces:s}=t,{done:i,resolve:r,reject:n}=ie(v,"Session update request expired without receiving any acknowledgement"),o=j(),c=me().toString(),l=this.client.session.get(e).namespaces;return this.events.once(f("session_update",o),({error:p})=>{p?n(p):r()}),await this.client.session.update(e,{namespaces:s}),await this.sendRequest({topic:e,method:"wc_sessionUpdate",params:{namespaces:s},throwOnFailedPublish:!0,clientRpcId:o,relayRpcId:c}).catch(p=>{this.client.logger.error(p),this.client.session.update(e,{namespaces:l}),n(p)}),{acknowledged:i}},this.extend=async t=>{this.isInitialized(),await this.confirmOnlineStateOrThrow();try{await this.isValidExtend(t)}catch(o){throw this.client.logger.error("extend() -> isValidExtend() failed"),o}const{topic:e}=t,s=j(),{done:i,resolve:r,reject:n}=ie(v,"Session extend request expired without receiving any acknowledgement");return this.events.once(f("session_extend",s),({error:o})=>{o?n(o):r()}),await this.setExpiry(e,N(Z)),this.sendRequest({topic:e,method:"wc_sessionExtend",params:{},clientRpcId:s,throwOnFailedPublish:!0}).catch(o=>{n(o)}),{acknowledged:i}},this.request=async t=>{this.isInitialized();try{await this.isValidRequest(t)}catch(h){throw this.client.logger.error("request() -> isValidRequest() failed"),h}const{chainId:e,request:s,topic:i,expiry:r=T.wc_sessionRequest.req.ttl}=t,n=this.client.session.get(i);n?.transportType===I.relay&&await this.confirmOnlineStateOrThrow();const o=j(),c=me().toString(),{done:l,resolve:p,reject:g}=ie(r,"Request expired. Please try again.");this.events.once(f("session_request",o),({error:h,result:w})=>{h?g(h):p(w)});const y="wc_sessionRequest",u=this.getAppLinkIfEnabled(n.peer.metadata,n.transportType);if(u)return await this.sendRequest({clientRpcId:o,relayRpcId:c,topic:i,method:y,params:{request:{...s,expiryTimestamp:N(r)},chainId:e},expiry:r,throwOnFailedPublish:!0,appLink:u}).catch(h=>g(h)),this.client.events.emit("session_request_sent",{topic:i,request:s,chainId:e,id:o}),await l();const m={request:{...s,expiryTimestamp:N(r)},chainId:e};return await Promise.all([new Promise(async h=>{await this.sendRequest({clientRpcId:o,relayRpcId:c,topic:i,method:y,params:m,expiry:r,throwOnFailedPublish:!0,tvf:this.getTVFParams(o,m)}).catch(w=>g(w)),this.client.events.emit("session_request_sent",{topic:i,request:s,chainId:e,id:o}),h()}),new Promise(async h=>{if(!n.sessionConfig?.disableDeepLink){const w=await bt(this.client.core.storage,Ce);await At({id:o,topic:i,wcDeepLink:w})}h()}),l()]).then(h=>h[2])},this.respond=async t=>{this.isInitialized();const e=this.client.core.eventClient.createEvent({properties:{topic:t?.topic||t?.response?.id?.toString(),trace:[C.session_request_response_started]}});try{await this.isValidRespond(t)}catch(c){throw e.addTrace(c?.message),e.setError(Y.session_request_response_validation_failure),c}e.addTrace(C.session_request_response_validation_success);const{topic:s,response:i}=t,{id:r}=i,n=this.client.session.get(s);n.transportType===I.relay&&await this.confirmOnlineStateOrThrow();const o=this.getAppLinkIfEnabled(n.peer.metadata,n.transportType);try{e.addTrace(C.session_request_response_publish_started),Q(i)?await this.sendResult({id:r,topic:s,result:i.result,throwOnFailedPublish:!0,appLink:o}):H(i)&&await this.sendError({id:r,topic:s,error:i.error,appLink:o}),this.cleanupAfterResponse(t)}catch(c){throw e.addTrace(c?.message),e.setError(Y.session_request_response_publish_failure),c}},this.ping=async t=>{this.isInitialized(),await this.confirmOnlineStateOrThrow();try{await this.isValidPing(t)}catch(s){throw this.client.logger.error("ping() -> isValidPing() failed"),s}const{topic:e}=t;if(this.client.session.keys.includes(e)){const s=j(),i=me().toString(),{done:r,resolve:n,reject:o}=ie(v,"Ping request expired without receiving any acknowledgement");this.events.once(f("session_ping",s),({error:c})=>{c?o(c):n()}),await Promise.all([this.sendRequest({topic:e,method:"wc_sessionPing",params:{},throwOnFailedPublish:!0,clientRpcId:s,relayRpcId:i}),r()])}else this.client.core.pairing.pairings.keys.includes(e)&&(this.client.logger.warn("ping() on pairing topic is deprecated and will be removed in the next major release."),await this.client.core.pairing.ping({topic:e}))},this.emit=async t=>{this.isInitialized(),await this.confirmOnlineStateOrThrow(),await this.isValidEmit(t);const{topic:e,event:s,chainId:i}=t,r=me().toString(),n=j();await this.sendRequest({topic:e,method:"wc_sessionEvent",params:{event:s,chainId:i},throwOnFailedPublish:!0,relayRpcId:r,clientRpcId:n})},this.disconnect=async t=>{this.isInitialized(),await this.confirmOnlineStateOrThrow(),await this.isValidDisconnect(t);const{topic:e}=t;if(this.client.session.keys.includes(e))await this.sendRequest({topic:e,method:"wc_sessionDelete",params:D("USER_DISCONNECTED"),throwOnFailedPublish:!0}),await this.deleteSession({topic:e,emitEvent:!1});else if(this.client.core.pairing.pairings.keys.includes(e))await this.client.core.pairing.disconnect({topic:e});else{const{message:s}=d("MISMATCHED_TOPIC",`Session or pairing topic not found: ${e}`);throw new Error(s)}},this.find=t=>(this.isInitialized(),this.client.session.getAll().filter(e=>xt(e,t))),this.getPendingSessionRequests=()=>this.client.pendingRequest.getAll(),this.authenticate=async(t,e)=>{this.isInitialized(),this.isValidAuthenticate(t);const s=e&&this.client.core.linkModeSupportedApps.includes(e)&&this.client.metadata.redirect?.linkMode,i=s?I.link_mode:I.relay;i===I.relay&&await this.confirmOnlineStateOrThrow();const{chains:r,statement:n="",uri:o,domain:c,nonce:l,type:p,exp:g,nbf:y,methods:u=[],expiry:m}=t,h=[...t.resources||[]],{topic:w,uri:_}=await this.client.core.pairing.create({methods:["wc_sessionAuthenticate"],transportType:i});if(this.client.logger.info({message:"Generated new pairing",pairing:{topic:w,uri:_}}),this.client.auth.authKeys.keys.includes($)){const{responseTopic:R,publicKey:q}=this.client.auth.authKeys.get($);R&&(await this.client.core.relayer.unsubscribe(R).catch(x=>this.client.logger.warn(x)),await this.client.auth.pairingTopics.delete(R,{message:"replaced",code:0}).catch(x=>this.client.logger.warn(x))),q&&this.client.core.crypto.keychain.has(q)&&await this.client.core.crypto.deleteKeyPair(q)}const S=await this.client.core.crypto.generateKeyPair(),b=qe(S);if(await Promise.all([this.client.auth.authKeys.set($,{responseTopic:b,publicKey:S}),this.client.auth.pairingTopics.set(b,{topic:b,pairingTopic:w})]),await this.client.core.relayer.subscribe(b,{transportType:i}),this.client.logger.info(`sending request to new pairing topic: ${w}`),u.length>0){const{namespace:R}=ve(r[0]);let q=Ct(R,"request",u);Pe(h)&&(q=kt(q,h.pop())),h.push(q)}const O=m&&m>T.wc_sessionAuthenticate.req.ttl?m:T.wc_sessionAuthenticate.req.ttl,L={authPayload:{type:p??"caip122",chains:r,statement:n,aud:o,domain:c,version:"1",nonce:l,iat:new Date().toISOString(),exp:g,nbf:y,resources:h},requester:{publicKey:S,metadata:this.client.metadata},expiryTimestamp:N(O)},P={eip155:{chains:r,methods:[...new Set(["personal_sign",...u])],events:["chainChanged","accountsChanged"]}},E={requiredNamespaces:{},optionalNamespaces:P,relays:[{protocol:"irn"}],pairingTopic:w,proposer:{publicKey:S,metadata:this.client.metadata},expiryTimestamp:N(T.wc_sessionPropose.req.ttl),id:j()},{done:A,resolve:K,reject:U}=ie(O,"Request expired"),M=j(),ee=f("session_connect",E.id),oe=f("session_request",M),te=async({error:R,session:q})=>{this.events.off(oe,ae),R?U(R):q&&K({session:q})},ae=async R=>{if(await this.deletePendingAuthRequest(M,{message:"fulfilled",code:0}),R.error){const le=D("WC_METHOD_UNSUPPORTED","wc_sessionAuthenticate");return R.error.code===le.code?void 0:(this.events.off(ee,te),U(R.error.message))}await this.deleteProposal(E.id),this.events.off(ee,te);const{cacaos:q,responder:x}=R.result,Ee=[],Ve=[];for(const le of q){await Me({cacao:le,projectId:this.client.core.projectId})||(this.client.logger.error(le,"Signature verification failed"),U(D("SESSION_SETTLEMENT_FAILED","Signature verification failed")));const{p:Re}=le,Ie=Pe(Re.resources),Le=[$e(Re.iss)],yt=Ke(Re.iss);if(Ie){const Te=Ue(Ie),wt=Ge(Ie);Ee.push(...Te),Le.push(...wt)}for(const Te of Le)Ve.push(`${Te}:${yt}`)}const ce=await this.client.core.crypto.generateSharedKey(S,x.publicKey);let ye;Ee.length>0&&(ye={topic:ce,acknowledged:!0,self:{publicKey:S,metadata:this.client.metadata},peer:x,controller:x.publicKey,expiry:N(Z),requiredNamespaces:{},optionalNamespaces:{},relay:{protocol:"irn"},pairingTopic:w,namespaces:Fe([...new Set(Ee)],[...new Set(Ve)]),transportType:i},await this.client.core.relayer.subscribe(ce,{transportType:i}),await this.client.session.set(ce,ye),w&&await this.client.core.pairing.updateMetadata({topic:w,metadata:x.metadata}),ye=this.client.session.get(ce)),this.client.metadata.redirect?.linkMode&&x.metadata.redirect?.linkMode&&x.metadata.redirect?.universal&&e&&(this.client.core.addLinkModeSupportedApp(x.metadata.redirect.universal),this.client.session.update(ce,{transportType:I.link_mode})),K({auths:q,session:ye})};this.events.once(ee,te),this.events.once(oe,ae);let ge;try{if(s){const R=ne("wc_sessionAuthenticate",L,M);this.client.core.history.set(w,R);const q=await this.client.core.crypto.encode("",R,{type:Vt,encoding:he});ge=we(e,w,q)}else await Promise.all([this.sendRequest({topic:w,method:"wc_sessionAuthenticate",params:L,expiry:t.expiry,throwOnFailedPublish:!0,clientRpcId:M}),this.sendRequest({topic:w,method:"wc_sessionPropose",params:E,expiry:T.wc_sessionPropose.req.ttl,throwOnFailedPublish:!0,clientRpcId:E.id})])}catch(R){throw this.events.off(ee,te),this.events.off(oe,ae),R}return await this.setProposal(E.id,E),await this.setAuthRequest(M,{request:{...L,verifyContext:{}},pairingTopic:w,transportType:i}),{uri:ge??_,response:A}},this.approveSessionAuthenticate=async t=>{const{id:e,auths:s}=t,i=this.client.core.eventClient.createEvent({properties:{topic:e.toString(),trace:[X.authenticated_session_approve_started]}});try{this.isInitialized()}catch(h){throw i.setError(pe.no_internet_connection),h}const r=this.getPendingAuthRequest(e);if(!r)throw i.setError(pe.authenticated_session_pending_request_not_found),new Error(`Could not find pending auth request with id ${e}`);const n=r.transportType||I.relay;n===I.relay&&await this.confirmOnlineStateOrThrow();const o=r.requester.publicKey,c=await this.client.core.crypto.generateKeyPair(),l=qe(o),p={type:Ne,receiverPublicKey:o,senderPublicKey:c},g=[],y=[];for(const h of s){if(!await Me({cacao:h,projectId:this.client.core.projectId})){i.setError(pe.invalid_cacao);const O=D("SESSION_SETTLEMENT_FAILED","Signature verification failed");throw await this.sendError({id:e,topic:l,error:O,encodeOpts:p}),new Error(O.message)}i.addTrace(X.cacaos_verified);const{p:w}=h,_=Pe(w.resources),S=[$e(w.iss)],b=Ke(w.iss);if(_){const O=Ue(_),L=Ge(_);g.push(...O),S.push(...L)}for(const O of S)y.push(`${O}:${b}`)}const u=await this.client.core.crypto.generateSharedKey(c,o);i.addTrace(X.create_authenticated_session_topic);let m;if(g?.length>0){m={topic:u,acknowledged:!0,self:{publicKey:c,metadata:this.client.metadata},peer:{publicKey:o,metadata:r.requester.metadata},controller:o,expiry:N(Z),authentication:s,requiredNamespaces:{},optionalNamespaces:{},relay:{protocol:"irn"},pairingTopic:r.pairingTopic,namespaces:Fe([...new Set(g)],[...new Set(y)]),transportType:n},i.addTrace(X.subscribing_authenticated_session_topic);try{await this.client.core.relayer.subscribe(u,{transportType:n})}catch(h){throw i.setError(pe.subscribe_authenticated_session_topic_failure),h}i.addTrace(X.subscribe_authenticated_session_topic_success),await this.client.session.set(u,m),i.addTrace(X.store_authenticated_session),await this.client.core.pairing.updateMetadata({topic:r.pairingTopic,metadata:r.requester.metadata})}i.addTrace(X.publishing_authenticated_session_approve);try{await this.sendResult({topic:l,id:e,result:{cacaos:s,responder:{publicKey:c,metadata:this.client.metadata}},encodeOpts:p,throwOnFailedPublish:!0,appLink:this.getAppLinkIfEnabled(r.requester.metadata,n)})}catch(h){throw i.setError(pe.authenticated_session_approve_publish_failure),h}return await this.client.auth.requests.delete(e,{message:"fulfilled",code:0}),await this.client.core.pairing.activate({topic:r.pairingTopic}),this.client.core.eventClient.deleteEvent({eventId:i.eventId}),{session:m}},this.rejectSessionAuthenticate=async t=>{this.isInitialized();const{id:e,reason:s}=t,i=this.getPendingAuthRequest(e);if(!i)throw new Error(`Could not find pending auth request with id ${e}`);i.transportType===I.relay&&await this.confirmOnlineStateOrThrow();const r=i.requester.publicKey,n=await this.client.core.crypto.generateKeyPair(),o=qe(r),c={type:Ne,receiverPublicKey:r,senderPublicKey:n};await this.sendError({id:e,topic:o,error:s,encodeOpts:c,rpcOpts:T.wc_sessionAuthenticate.reject,appLink:this.getAppLinkIfEnabled(i.requester.metadata,i.transportType)}),await this.client.auth.requests.delete(e,{message:"rejected",code:0}),await this.deleteProposal(e)},this.formatAuthMessage=t=>{this.isInitialized();const{request:e,iss:s}=t;return Lt(e,s)},this.processRelayMessageCache=()=>{setTimeout(async()=>{if(this.relayMessageCache.length!==0)for(;this.relayMessageCache.length>0;)try{const t=this.relayMessageCache.shift();t&&await this.onRelayMessage(t)}catch(t){this.client.logger.error(t)}},50)},this.cleanupDuplicatePairings=async t=>{if(t.pairingTopic)try{const e=this.client.core.pairing.pairings.get(t.pairingTopic),s=this.client.core.pairing.pairings.getAll().filter(i=>i.peerMetadata?.url&&i.peerMetadata?.url===t.peer.metadata.url&&i.topic&&i.topic!==e.topic);if(s.length===0)return;this.client.logger.info(`Cleaning up ${s.length} duplicate pairing(s)`),await Promise.all(s.map(i=>this.client.core.pairing.disconnect({topic:i.topic}))),this.client.logger.info("Duplicate pairings clean up finished")}catch(e){this.client.logger.error(e)}},this.deleteSession=async t=>{const{topic:e,expirerHasDeleted:s=!1,emitEvent:i=!0,id:r=0}=t,{self:n}=this.client.session.get(e);await this.client.core.relayer.unsubscribe(e),await this.client.session.delete(e,D("USER_DISCONNECTED")),this.addToRecentlyDeleted(e,"session"),this.client.core.crypto.keychain.has(n.publicKey)&&await this.client.core.crypto.deleteKeyPair(n.publicKey),this.client.core.crypto.keychain.has(e)&&await this.client.core.crypto.deleteSymKey(e),s||this.client.core.expirer.del(e),this.client.core.storage.removeItem(Ce).catch(o=>this.client.logger.warn(o)),e===this.sessionRequestQueue.queue[0]?.topic&&(this.sessionRequestQueue.state=V.idle),await Promise.all(this.getPendingSessionRequests().filter(o=>o.topic===e).map(o=>this.deletePendingSessionRequest(o.id,D("USER_DISCONNECTED")))),i&&this.client.events.emit("session_delete",{id:r,topic:e})},this.deleteProposal=async(t,e)=>{if(e)try{const s=this.client.proposal.get(t);this.client.core.eventClient.getEvent({topic:s.pairingTopic})?.setError(Y.proposal_expired)}catch{}await Promise.all([this.client.proposal.delete(t,D("USER_DISCONNECTED")),e?Promise.resolve():this.client.core.expirer.del(t)]),this.addToRecentlyDeleted(t,"proposal")},this.deletePendingSessionRequest=async(t,e,s=!1)=>{await Promise.all([this.client.pendingRequest.delete(t,e),s?Promise.resolve():this.client.core.expirer.del(t)]),this.addToRecentlyDeleted(t,"request"),this.sessionRequestQueue.queue=this.sessionRequestQueue.queue.filter(i=>i.id!==t),s&&(this.sessionRequestQueue.state=V.idle,this.client.events.emit("session_request_expire",{id:t}))},this.deletePendingAuthRequest=async(t,e,s=!1)=>{await Promise.all([this.client.auth.requests.delete(t,e),s?Promise.resolve():this.client.core.expirer.del(t)])},this.setExpiry=async(t,e)=>{this.client.session.keys.includes(t)&&(this.client.core.expirer.set(t,e),await this.client.session.update(t,{expiry:e}))},this.setProposal=async(t,e)=>{this.client.core.expirer.set(t,N(T.wc_sessionPropose.req.ttl)),await this.client.proposal.set(t,e)},this.setAuthRequest=async(t,e)=>{const{request:s,pairingTopic:i,transportType:r=I.relay}=e;this.client.core.expirer.set(t,s.expiryTimestamp),await this.client.auth.requests.set(t,{authPayload:s.authPayload,requester:s.requester,expiryTimestamp:s.expiryTimestamp,id:t,pairingTopic:i,verifyContext:s.verifyContext,transportType:r})},this.setPendingSessionRequest=async t=>{const{id:e,topic:s,params:i,verifyContext:r}=t,n=i.request.expiryTimestamp||N(T.wc_sessionRequest.req.ttl);this.client.core.expirer.set(e,n),await this.client.pendingRequest.set(e,{id:e,topic:s,params:i,verifyContext:r})},this.sendRequest=async t=>{const{topic:e,method:s,params:i,expiry:r,relayRpcId:n,clientRpcId:o,throwOnFailedPublish:c,appLink:l,tvf:p,publishOpts:g={}}=t,y=ne(s,i,o);let u;const m=!!l;try{const _=m?he:J;u=await this.client.core.crypto.encode(e,y,{encoding:_})}catch(_){throw await this.cleanup(),this.client.logger.error(`sendRequest() -> core.crypto.encode() for topic ${e} failed`),_}let h;if(ot.includes(s)){const _=G(JSON.stringify(y)),S=G(u);h=await this.client.core.verify.register({id:S,decryptedId:_})}const w={...T[s].req,...g};if(w.attestation=h,r&&(w.ttl=r),n&&(w.id=n),this.client.core.history.set(e,y),m){const _=we(l,e,u);await global.Linking.openURL(_,this.client.name)}else w.tvf={...p,correlationId:y.id},c?(w.internal={...w.internal,throwOnFailedPublish:!0},await this.client.core.relayer.publish(e,u,w)):this.client.core.relayer.publish(e,u,w).catch(_=>this.client.logger.error(_));return y.id},this.sendProposeSession=async t=>{const{proposal:e,publishOpts:s}=t,i=ne("wc_sessionPropose",e,e.id);this.client.core.history.set(e.pairingTopic,i);const r=await this.client.core.crypto.encode(e.pairingTopic,i,{encoding:J}),n=G(JSON.stringify(i)),o=G(r),c=await this.client.core.verify.register({id:o,decryptedId:n});await this.client.core.relayer.publishCustom({payload:{pairingTopic:e.pairingTopic,sessionProposal:r},opts:{...s,publishMethod:"wc_proposeSession",attestation:c}})},this.sendApproveSession=async t=>{const{sessionTopic:e,pairingProposalResponse:s,proposal:i,sessionSettleRequest:r,publishOpts:n}=t,o=et(i.id,s),c=await this.client.core.crypto.encode(i.pairingTopic,o,{encoding:J}),l=ne("wc_sessionSettle",r,n?.id),p=await this.client.core.crypto.encode(e,l,{encoding:J});this.client.core.history.set(e,l),await this.client.core.relayer.publishCustom({payload:{sessionTopic:e,pairingTopic:i.pairingTopic,sessionProposalResponse:c,sessionSettlementRequest:p},opts:{...n,publishMethod:"wc_approveSession"}})},this.sendResult=async t=>{const{id:e,topic:s,result:i,throwOnFailedPublish:r,encodeOpts:n,appLink:o}=t,c=et(e,i);let l;const p=o&&typeof global?.Linking<"u";try{const u=p?he:J;l=await this.client.core.crypto.encode(s,c,{...n||{},encoding:u})}catch(u){throw await this.cleanup(),this.client.logger.error(`sendResult() -> core.crypto.encode() for topic ${s} failed`),u}let g,y;try{g=await this.client.core.history.get(s,e);const u=g.request;try{y=this.getTVFParams(e,u.params,i)}catch(m){this.client.logger.warn(`sendResult() -> getTVFParams() failed: ${m?.message}`)}}catch(u){throw this.client.logger.error(`sendResult() -> history.get(${s}, ${e}) failed`),u}if(p){const u=we(o,s,l);await global.Linking.openURL(u,this.client.name)}else{const u=g.request.method,m=T[u].res;m.tvf={...y,correlationId:e},r?(m.internal={...m.internal,throwOnFailedPublish:!0},await this.client.core.relayer.publish(s,l,m)):this.client.core.relayer.publish(s,l,m).catch(h=>this.client.logger.error(h))}await this.client.core.history.resolve(c)},this.sendError=async t=>{const{id:e,topic:s,error:i,encodeOpts:r,rpcOpts:n,appLink:o}=t,c=hs(e,i);let l;const p=o&&typeof global?.Linking<"u";try{const y=p?he:J;l=await this.client.core.crypto.encode(s,c,{...r||{},encoding:y})}catch(y){throw await this.cleanup(),this.client.logger.error(`sendError() -> core.crypto.encode() for topic ${s} failed`),y}let g;try{g=await this.client.core.history.get(s,e)}catch(y){throw this.client.logger.error(`sendError() -> history.get(${s}, ${e}) failed`),y}if(p){const y=we(o,s,l);await global.Linking.openURL(y,this.client.name)}else{const y=g.request.method,u=n||T[y].res;this.client.core.relayer.publish(s,l,u)}await this.client.core.history.resolve(c)},this.cleanup=async()=>{const t=[],e=[];this.client.session.getAll().forEach(s=>{let i=!1;re(s.expiry)&&(i=!0),this.client.core.crypto.keychain.has(s.topic)||(i=!0),i&&t.push(s.topic)}),this.client.proposal.getAll().forEach(s=>{re(s.expiryTimestamp)&&e.push(s.id)}),await Promise.all([...t.map(s=>this.deleteSession({topic:s})),...e.map(s=>this.deleteProposal(s))])},this.onProviderMessageEvent=async t=>{!this.initialized||this.relayMessageCache.length>0?this.relayMessageCache.push(t):await this.onRelayMessage(t)},this.onRelayEventRequest=async t=>{this.requestQueue.queue.push(t),await this.processRequestsQueue()},this.processRequestsQueue=async()=>{if(this.requestQueue.state===V.active){this.client.logger.info("Request queue already active, skipping...");return}for(this.client.logger.info(`Request queue starting with ${this.requestQueue.queue.length} requests`);this.requestQueue.queue.length>0;){this.requestQueue.state=V.active;const t=this.requestQueue.queue.shift();if(t)try{await this.processRequest(t)}catch(e){this.client.logger.warn(e)}}this.requestQueue.state=V.idle},this.processRequest=async t=>{const{topic:e,payload:s,attestation:i,transportType:r,encryptedId:n}=t,o=s.method;if(!this.shouldIgnorePairingRequest({topic:e,requestMethod:o}))switch(o){case"wc_sessionPropose":return await this.onSessionProposeRequest({topic:e,payload:s,attestation:i,encryptedId:n});case"wc_sessionSettle":return await this.onSessionSettleRequest(e,s);case"wc_sessionUpdate":return await this.onSessionUpdateRequest(e,s);case"wc_sessionExtend":return await this.onSessionExtendRequest(e,s);case"wc_sessionPing":return await this.onSessionPingRequest(e,s);case"wc_sessionDelete":return await this.onSessionDeleteRequest(e,s);case"wc_sessionRequest":return await this.onSessionRequest({topic:e,payload:s,attestation:i,encryptedId:n,transportType:r});case"wc_sessionEvent":return await this.onSessionEventRequest(e,s);case"wc_sessionAuthenticate":return await this.onSessionAuthenticateRequest({topic:e,payload:s,attestation:i,encryptedId:n,transportType:r});default:return this.client.logger.info(`Unsupported request method ${o}`)}},this.onRelayEventResponse=async t=>{const{topic:e,payload:s,transportType:i}=t,r=(await this.client.core.history.get(e,s.id)).request.method;switch(r){case"wc_sessionPropose":return this.onSessionProposeResponse(e,s,i);case"wc_sessionSettle":return this.onSessionSettleResponse(e,s);case"wc_sessionUpdate":return this.onSessionUpdateResponse(e,s);case"wc_sessionExtend":return this.onSessionExtendResponse(e,s);case"wc_sessionPing":return this.onSessionPingResponse(e,s);case"wc_sessionRequest":return this.onSessionRequestResponse(e,s);case"wc_sessionAuthenticate":return this.onSessionAuthenticateResponse(e,s);default:return this.client.logger.info(`Unsupported response method ${r}`)}},this.onRelayEventUnknownPayload=t=>{const{topic:e}=t,{message:s}=d("MISSING_OR_INVALID",`Decoded payload on topic ${e} is not identifiable as a JSON-RPC request or a response.`);throw new Error(s)},this.shouldIgnorePairingRequest=t=>{const{topic:e,requestMethod:s}=t,i=this.expectedPairingMethodMap.get(e);return!i||i.includes(s)?!1:!!(i.includes("wc_sessionAuthenticate")&&this.client.events.listenerCount("session_authenticate")>0)},this.onSessionProposeRequest=async t=>{const{topic:e,payload:s,attestation:i,encryptedId:r}=t,{params:n,id:o}=s;try{const c=this.client.core.eventClient.getEvent({topic:e});this.client.events.listenerCount("session_proposal")===0&&(console.warn("No listener for session_proposal event"),c?.setError(St.proposal_listener_not_found)),this.isValidConnect({...s.params});const l=n.expiryTimestamp||N(T.wc_sessionPropose.req.ttl),p={id:o,pairingTopic:e,expiryTimestamp:l,attestation:i,encryptedId:r,...n};await this.setProposal(o,p);const g=await this.getVerifyContext({attestationId:i,hash:G(JSON.stringify(s)),encryptedId:r,metadata:p.proposer.metadata});c?.addTrace(Et.emit_session_proposal),this.client.events.emit("session_proposal",{id:o,params:p,verifyContext:g})}catch(c){await this.sendError({id:o,topic:e,error:c,rpcOpts:T.wc_sessionPropose.autoReject}),this.client.logger.error(c)}},this.onSessionProposeResponse=async(t,e,s)=>{const{id:i}=e;if(Q(e)){const{result:r}=e;this.client.logger.trace({type:"method",method:"onSessionProposeResponse",result:r});const n=this.client.proposal.get(i);this.client.logger.trace({type:"method",method:"onSessionProposeResponse",proposal:n});const o=n.proposer.publicKey;this.client.logger.trace({type:"method",method:"onSessionProposeResponse",selfPublicKey:o});const c=r.responderPublicKey;this.client.logger.trace({type:"method",method:"onSessionProposeResponse",peerPublicKey:c});const l=await this.client.core.crypto.generateSharedKey(o,c);this.pendingSessions.set(i,{sessionTopic:l,pairingTopic:t,proposalId:i,publicKey:o});const p=await this.client.core.relayer.subscribe(l,{transportType:s});this.client.logger.trace({type:"method",method:"onSessionProposeResponse",subscriptionId:p}),await this.client.core.pairing.activate({topic:t})}else if(H(e)){await this.deleteProposal(i);const r=f("session_connect",i);if(this.events.listenerCount(r)===0)throw new Error(`emitting ${r} without any listeners, 954`);this.events.emit(r,{error:e.error})}},this.onSessionSettleRequest=async(t,e)=>{const{id:s,params:i}=e;try{this.isValidSessionSettleRequest(i);const{relay:r,controller:n,expiry:o,namespaces:c,sessionProperties:l,scopedProperties:p,sessionConfig:g,proposalRequestsResponses:y}=e.params,u=[...this.pendingSessions.values()].find(w=>w.sessionTopic===t);if(!u)return this.client.logger.error(`Pending session not found for topic ${t}`);const m=this.client.proposal.get(u.proposalId),h={topic:t,relay:r,expiry:o,namespaces:c,acknowledged:!0,pairingTopic:u.pairingTopic,requiredNamespaces:m.requiredNamespaces,optionalNamespaces:m.optionalNamespaces,controller:n.publicKey,self:{publicKey:u.publicKey,metadata:this.client.metadata},peer:{publicKey:n.publicKey,metadata:n.metadata},...l&&{sessionProperties:l},...p&&{scopedProperties:p},...g&&{sessionConfig:g},transportType:I.relay,authentication:y?.authentication,walletPayResult:y?.walletPay};await this.client.session.set(h.topic,h),await this.setExpiry(h.topic,h.expiry),await this.client.core.pairing.updateMetadata({topic:u.pairingTopic,metadata:h.peer.metadata}),this.pendingSessions.delete(u.proposalId),this.deleteProposal(u.proposalId,!1),this.cleanupDuplicatePairings(h),await this.sendResult({id:e.id,topic:t,throwOnFailedPublish:!0,result:!0}),this.client.events.emit("session_connect",{session:h}),this.events.emit(f("session_connect",u.proposalId),{session:h})}catch(r){await this.sendError({id:s,topic:t,error:r}),this.client.logger.error(r)}},this.onSessionSettleResponse=async(t,e)=>{const{id:s}=e;Q(e)?(await this.client.session.update(t,{acknowledged:!0}),this.events.emit(f("session_approve",s),{})):H(e)&&(await this.deleteSession({topic:t,emitEvent:!1}),this.events.emit(f("session_approve",s),{error:e.error}))},this.onSessionUpdateRequest=async(t,e)=>{const{params:s,id:i}=e;try{const r=`${t}_session_update`,n=de.get(r);if(n&&this.isRequestOutOfSync(n,i)){this.client.logger.warn(`Discarding out of sync request - ${i}`),this.sendError({id:i,topic:t,error:D("INVALID_UPDATE_REQUEST")});return}this.isValidUpdate({topic:t,...s});try{de.set(r,i),await this.client.session.update(t,{namespaces:s.namespaces}),await this.sendResult({id:i,topic:t,result:!0})}catch(o){throw de.delete(r),o}this.client.events.emit("session_update",{id:i,topic:t,params:s})}catch(r){await this.sendError({id:i,topic:t,error:r}),this.client.logger.error(r)}},this.isRequestOutOfSync=(t,e)=>e.toString().slice(0,-3)<t.toString().slice(0,-3),this.onSessionUpdateResponse=(t,e)=>{const{id:s}=e,i=f("session_update",s);if(this.events.listenerCount(i)===0)throw new Error(`emitting ${i} without any listeners`);Q(e)?this.events.emit(f("session_update",s),{}):H(e)&&this.events.emit(f("session_update",s),{error:e.error})},this.onSessionExtendRequest=async(t,e)=>{const{id:s}=e;try{this.isValidExtend({topic:t}),await this.setExpiry(t,N(Z)),await this.sendResult({id:s,topic:t,result:!0}),this.client.events.emit("session_extend",{id:s,topic:t})}catch(i){await this.sendError({id:s,topic:t,error:i}),this.client.logger.error(i)}},this.onSessionExtendResponse=(t,e)=>{const{id:s}=e,i=f("session_extend",s);if(this.events.listenerCount(i)===0)throw new Error(`emitting ${i} without any listeners`);Q(e)?this.events.emit(f("session_extend",s),{}):H(e)&&this.events.emit(f("session_extend",s),{error:e.error})},this.onSessionPingRequest=async(t,e)=>{const{id:s}=e;try{this.isValidPing({topic:t}),await this.sendResult({id:s,topic:t,result:!0,throwOnFailedPublish:!0}),this.client.events.emit("session_ping",{id:s,topic:t})}catch(i){await this.sendError({id:s,topic:t,error:i}),this.client.logger.error(i)}},this.onSessionPingResponse=(t,e)=>{const{id:s}=e,i=f("session_ping",s);setTimeout(()=>{if(this.events.listenerCount(i)===0)throw new Error(`emitting ${i} without any listeners 2176`);Q(e)?this.events.emit(f("session_ping",s),{}):H(e)&&this.events.emit(f("session_ping",s),{error:e.error})},500)},this.onSessionDeleteRequest=async(t,e)=>{const{id:s}=e;try{await this.isValidDisconnect({topic:t,reason:e.params}),this.cleanupPendingSentRequestsForTopic({topic:t,error:D("USER_DISCONNECTED")}),await this.deleteSession({topic:t,id:s})}catch(i){this.client.logger.error(i)}},this.onSessionRequest=async t=>{const{topic:e,payload:s,attestation:i,encryptedId:r,transportType:n}=t,{id:o,params:c}=s;try{await this.isValidRequest({topic:e,...c});const l=this.client.session.get(e),p=await this.getVerifyContext({attestationId:i,hash:G(JSON.stringify(ne("wc_sessionRequest",c,o))),encryptedId:r,metadata:l.peer.metadata,transportType:n}),g={id:o,topic:e,params:c,verifyContext:p};await this.setPendingSessionRequest(g),n===I.link_mode&&l.peer.metadata.redirect?.universal&&this.client.core.addLinkModeSupportedApp(l.peer.metadata.redirect?.universal),this.client.signConfig?.disableRequestQueue?this.emitSessionRequest(g):(this.addSessionRequestToSessionRequestQueue(g),this.processSessionRequestQueue())}catch(l){await this.sendError({id:o,topic:e,error:l}),this.client.logger.error(l)}},this.onSessionRequestResponse=(t,e)=>{const{id:s}=e,i=f("session_request",s);if(this.events.listenerCount(i)===0)throw new Error(`emitting ${i} without any listeners`);Q(e)?this.events.emit(f("session_request",s),{result:e.result}):H(e)&&this.events.emit(f("session_request",s),{error:e.error})},this.onSessionEventRequest=async(t,e)=>{const{id:s,params:i}=e;try{const r=`${t}_session_event_${i.event.name}`,n=de.get(r);if(n&&this.isRequestOutOfSync(n,s)){this.client.logger.info(`Discarding out of sync request - ${s}`);return}this.isValidEmit({topic:t,...i}),this.client.events.emit("session_event",{id:s,topic:t,params:i}),de.set(r,s)}catch(r){await this.sendError({id:s,topic:t,error:r}),this.client.logger.error(r)}},this.onSessionAuthenticateResponse=(t,e)=>{const{id:s}=e;this.client.logger.trace({type:"method",method:"onSessionAuthenticateResponse",topic:t,payload:e}),Q(e)?this.events.emit(f("session_request",s),{result:e.result}):H(e)&&this.events.emit(f("session_request",s),{error:e.error})},this.onSessionAuthenticateRequest=async t=>{const{topic:e,payload:s,attestation:i,encryptedId:r,transportType:n}=t;try{const{requester:o,authPayload:c,expiryTimestamp:l}=s.params,p=await this.getVerifyContext({attestationId:i,hash:G(JSON.stringify(s)),encryptedId:r,metadata:o.metadata,transportType:n}),g={requester:o,pairingTopic:e,id:s.id,authPayload:c,verifyContext:p,expiryTimestamp:l};await this.setAuthRequest(s.id,{request:g,pairingTopic:e,transportType:n}),n===I.link_mode&&o.metadata.redirect?.universal&&this.client.core.addLinkModeSupportedApp(o.metadata.redirect.universal),this.client.events.emit("session_authenticate",{topic:e,params:s.params,id:s.id,verifyContext:p})}catch(o){this.client.logger.error(o);const c=s.params.requester.publicKey,l=await this.client.core.crypto.generateKeyPair(),p=this.getAppLinkIfEnabled(s.params.requester.metadata,n),g={type:Ne,receiverPublicKey:c,senderPublicKey:l};await this.sendError({id:s.id,topic:e,error:o,encodeOpts:g,rpcOpts:T.wc_sessionAuthenticate.autoReject,appLink:p})}},this.addSessionRequestToSessionRequestQueue=t=>{this.sessionRequestQueue.queue.push(t)},this.cleanupAfterResponse=t=>{this.deletePendingSessionRequest(t.response.id,{message:"fulfilled",code:0}),setTimeout(()=>{this.sessionRequestQueue.state=V.idle,this.processSessionRequestQueue()},Ze(this.requestQueueDelay))},this.cleanupPendingSentRequestsForTopic=({topic:t,error:e})=>{const s=this.client.core.history.pending;s.length>0&&s.filter(i=>i.topic===t&&i.request.method==="wc_sessionRequest").forEach(i=>{this.events.emit(f("session_request",i.request.id),{error:e})})},this.processSessionRequestQueue=()=>{if(this.sessionRequestQueue.state===V.active){this.client.logger.info("session request queue is already active.");return}const t=this.sessionRequestQueue.queue[0];if(!t){this.client.logger.info("session request queue is empty.");return}try{this.emitSessionRequest(t)}catch(e){this.client.logger.error(e)}},this.emitSessionRequest=t=>{if(this.emittedSessionRequests.has(t.id)){this.client.logger.warn({id:t.id},`Skipping emitting \`session_request\` event for duplicate request. id: ${t.id}`);return}this.sessionRequestQueue.state=V.active,this.emittedSessionRequests.add(t.id),this.client.events.emit("session_request",t)},this.cleanupInProgress=!1,this.cleanupOrphanedSubscriptions=async()=>{const t=this.client.core.relayer.subscriber.topics;if(t.length===0)return;const e=new Set(this.client.session.keys),s=new Set(this.client.core.pairing.pairings.keys),i=new Set([...this.pendingSessions.values()].map(n=>n.sessionTopic));let r;if(this.client.auth.authKeys.keys.includes($)){const{responseTopic:n}=this.client.auth.authKeys.get($);r=n}for(const n of t)if(!e.has(n)&&!s.has(n)&&!i.has(n)&&n!==r){this.client.logger.info(`Cleaning up orphaned subscriber topic: ${n}`);try{await this.client.core.relayer.subscriber.unsubscribe(n)}catch(o){this.client.logger.warn(o,`Failed to clean up orphaned subscription: ${n}`)}}},this.onPairingCreated=t=>{if(t.methods&&this.expectedPairingMethodMap.set(t.topic,t.methods),t.active)return;const e=this.client.proposal.getAll().find(s=>s.pairingTopic===t.topic);e&&this.onSessionProposeRequest({topic:t.topic,payload:ne("wc_sessionPropose",{...e,requiredNamespaces:e.requiredNamespaces,optionalNamespaces:e.optionalNamespaces,relays:e.relays,proposer:e.proposer,sessionProperties:e.sessionProperties,scopedProperties:e.scopedProperties},e.id),attestation:e.attestation,encryptedId:e.encryptedId})},this.isValidConnect=async t=>{if(!k(t)){const{message:c}=d("MISSING_OR_INVALID",`connect() params: ${JSON.stringify(t)}`);throw new Error(c)}const{pairingTopic:e,requiredNamespaces:s,optionalNamespaces:i,sessionProperties:r,scopedProperties:n,relays:o}=t;if(B(e)||await this.isValidPairingTopic(e),!Dt(o,!0)){const{message:c}=d("MISSING_OR_INVALID",`connect() relays: ${o}`);throw new Error(c)}if(s&&!B(s)&&je(s)!==0){const c="requiredNamespaces are deprecated and are automatically assigned to optionalNamespaces";["fatal","error","silent"].includes(this.client.logger.level)?console.warn(c):this.client.logger.warn(c),this.validateNamespaces(s,"requiredNamespaces")}if(i&&!B(i)&&je(i)!==0&&this.validateNamespaces(i,"optionalNamespaces"),r&&!B(r)&&this.validateSessionProps(r,"sessionProperties"),n&&!B(n)){this.validateSessionProps(n,"scopedProperties");const c=Object.keys(s||{}).concat(Object.keys(i||{}));if(!Object.keys(n).every(l=>c.includes(l.split(":")[0])))throw new Error(`Scoped properties must be a subset of required/optional namespaces, received: ${JSON.stringify(n)}, required/optional namespaces: ${JSON.stringify(c)}`)}},this.validateNamespaces=(t,e)=>{const s=Mt(t,"connect()",e);if(s)throw new Error(s.message)},this.isValidApprove=async t=>{if(!k(t))throw new Error(d("MISSING_OR_INVALID",`approve() params: ${t}`).message);const{id:e,namespaces:s,relayProtocol:i,sessionProperties:r,scopedProperties:n}=t;this.checkRecentlyDeleted(e),await this.isValidProposalId(e);const o=this.client.proposal.get(e),c=Oe(s,"approve()");if(c)throw new Error(c.message);const l=Qe(o.requiredNamespaces,s,"approve()");if(l)throw new Error(l.message);if(!W(i,!0)){const{message:p}=d("MISSING_OR_INVALID",`approve() relayProtocol: ${i}`);throw new Error(p)}if(r&&!B(r)&&this.validateSessionProps(r,"sessionProperties"),n&&!B(n)){this.validateSessionProps(n,"scopedProperties");const p=new Set(Object.keys(s));if(!Object.keys(n).every(g=>p.has(g.split(":")[0])))throw new Error(`Scoped properties must be a subset of approved namespaces, received: ${JSON.stringify(n)}, approved namespaces: ${Array.from(p).join(", ")}`)}},this.isValidReject=async t=>{if(!k(t)){const{message:i}=d("MISSING_OR_INVALID",`reject() params: ${t}`);throw new Error(i)}const{id:e,reason:s}=t;if(this.checkRecentlyDeleted(e),await this.isValidProposalId(e),!$t(s)){const{message:i}=d("MISSING_OR_INVALID",`reject() reason: ${JSON.stringify(s)}`);throw new Error(i)}},this.isValidSessionSettleRequest=t=>{if(!k(t)){const{message:c}=d("MISSING_OR_INVALID",`onSessionSettleRequest() params: ${t}`);throw new Error(c)}const{relay:e,controller:s,namespaces:i,expiry:r}=t;