UNPKG

@walletconnect/sign-client

Version:
1 lines 69.9 kB
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var le=require("events"),p=require("@walletconnect/core"),pe=require("@walletconnect/types"),i=require("@walletconnect/utils"),ve=require("@walletconnect/logger"),S=require("@walletconnect/time"),m=require("@walletconnect/jsonrpc-utils");function qe(O){return O&&O.__esModule?O:{default:O}}var Oe=qe(le);const se="wc",ie=2,re="client",X=`${se}@${ie}:${re}:`,z={name:re,logger:"error",controller:!1,relayUrl:"wss://relay.walletconnect.org"},Ae={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"},Ce={database:":memory:"},ne="WALLETCONNECT_DEEPLINK_CHOICE",Ve={created:"history_created",updated:"history_updated",deleted:"history_deleted",sync:"history_sync"},xe="history",Le="0.3",he="proposal",be=S.THIRTY_DAYS,ae="Proposal expired",de="session",M=S.SEVEN_DAYS,ue="engine",N={wc_sessionPropose:{req:{ttl:S.FIVE_MINUTES,prompt:!0,tag:1100},res:{ttl:S.FIVE_MINUTES,prompt:!1,tag:1101},reject:{ttl:S.FIVE_MINUTES,prompt:!1,tag:1120},autoReject:{ttl:S.FIVE_MINUTES,prompt:!1,tag:1121}},wc_sessionSettle:{req:{ttl:S.FIVE_MINUTES,prompt:!1,tag:1102},res:{ttl:S.FIVE_MINUTES,prompt:!1,tag:1103}},wc_sessionUpdate:{req:{ttl:S.ONE_DAY,prompt:!1,tag:1104},res:{ttl:S.ONE_DAY,prompt:!1,tag:1105}},wc_sessionExtend:{req:{ttl:S.ONE_DAY,prompt:!1,tag:1106},res:{ttl:S.ONE_DAY,prompt:!1,tag:1107}},wc_sessionRequest:{req:{ttl:S.FIVE_MINUTES*3,prompt:!0,tag:1108},res:{ttl:S.FIVE_MINUTES*3,prompt:!1,tag:1109}},wc_sessionEvent:{req:{ttl:S.FIVE_MINUTES,prompt:!0,tag:1110},res:{ttl:S.FIVE_MINUTES,prompt:!1,tag:1111}},wc_sessionDelete:{req:{ttl:S.ONE_DAY,prompt:!1,tag:1112},res:{ttl:S.ONE_DAY,prompt:!1,tag:1113}},wc_sessionPing:{req:{ttl:S.ONE_DAY,prompt:!1,tag:1114},res:{ttl:S.ONE_DAY,prompt:!1,tag:1115}},wc_sessionAuthenticate:{req:{ttl:S.ONE_HOUR,prompt:!0,tag:1116},res:{ttl:S.ONE_HOUR,prompt:!1,tag:1117},reject:{ttl:S.FIVE_MINUTES,prompt:!1,tag:1118},autoReject:{ttl:S.FIVE_MINUTES,prompt:!1,tag:1119}}},B={min:S.FIVE_MINUTES,max:S.SEVEN_DAYS},C={idle:"IDLE",active:"ACTIVE"},ge={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:""}},Ee="request",ye=["wc_sessionPropose","wc_sessionRequest","wc_authRequest","wc_sessionAuthenticate"],_e="wc",Me=1.5,me="auth",Se="authKeys",we="pairingTopics",Te="requests",Y=`${_e}@${1.5}:${me}:`,H=`${Y}:PUB_KEY`;class De extends pe.IEngine{constructor(c){super(c),this.name=ue,this.events=new Oe.default,this.initialized=!1,this.requestQueue={state:C.idle,queue:[]},this.sessionRequestQueue={state:C.idle,queue:[]},this.emittedSessionRequests=new i.LimitedSet({limit:500}),this.requestQueueDelay=S.ONE_SECOND,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(),await this.registerLinkModeListeners(),this.client.core.pairing.register({methods:Object.keys(N)}),this.initialized=!0,setTimeout(async()=>{await this.processPendingMessageEvents(),this.sessionRequestQueue.queue=this.getPendingSessionRequests(),this.processSessionRequestQueue()},S.toMiliseconds(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=i.mergeRequiredAndOptionalNamespaces(e.requiredNamespaces,e.optionalNamespaces),e.requiredNamespaces={};const{pairingTopic:s,requiredNamespaces:r,optionalNamespaces:n,sessionProperties:a,scopedProperties:o,relays:l,authentication:h,walletPay:d}=e,E=h?.[0]?.ttl||N.wc_sessionPropose.req.ttl||S.FIVE_MINUTES;this.validateRequestExpiry(E);let y=s,g,w=!1;try{if(y){const R=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."),w=R.active}}catch(R){throw this.client.logger.error(`connect() -> pairing.get(${y}) failed`),R}if(!y||!w){const{topic:R,uri:x}=await this.client.core.pairing.create({internal:{skipSubscribe:!0}});y=R,g=x}if(!y){const{message:R}=i.getInternalError("NO_MATCHING_KEY",`connect() pairing topic: ${y}`);throw new Error(R)}const u=await this.client.core.crypto.generateKeyPair(),_=i.calcExpiry(E),T={requiredNamespaces:r,optionalNamespaces:n,relays:l??[{protocol:p.RELAYER_DEFAULT_PROTOCOL}],proposer:{publicKey:u,metadata:this.client.metadata},expiryTimestamp:_,pairingTopic:y,...a&&{sessionProperties:a},...o&&{scopedProperties:o},id:m.payloadId(),...(h||d)&&{requests:{authentication:h?.map(R=>{const{domain:x,chains:j,nonce:U,uri:L,exp:D,nbf:$,type:k,statement:F,requestId:J,resources:P,signatureTypes:q}=R;return{domain:x,chains:j,nonce:U,type:k??"caip122",aud:L,version:"1",iat:new Date().toISOString(),exp:D,nbf:$,statement:F,requestId:J,resources:P,signatureTypes:q}}),walletPay:d}}},I=i.engineEvent("session_connect",T.id),{reject:A,resolve:v,done:V}=i.createDelayedPromise(E,ae),f=({id:R})=>{R===T.id&&(this.client.events.off("proposal_expire",f),this.pendingSessions.delete(T.id),this.events.emit(I,{error:{message:ae,code:0}}))};return this.client.events.on("proposal_expire",f),this.events.once(I,({error:R,session:x})=>{this.client.events.off("proposal_expire",f),R?A(R):x&&v(x)}),await this.setProposal(T.id,T),await this.sendProposeSession({proposal:T,publishOpts:{internal:{throwOnFailedPublish:!0},tvf:{correlationId:T.id}}}).catch(R=>{throw this.deleteProposal(T.id),R}),{uri:g,approval:V}},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:[p.EVENT_CLIENT_SESSION_TRACES.session_approve_started]}});try{this.isInitialized(),await this.confirmOnlineStateOrThrow()}catch(f){throw e.setError(p.EVENT_CLIENT_SESSION_ERRORS.no_internet_connection),f}try{await this.isValidProposalId(t?.id)}catch(f){throw this.client.logger.error(`approve() -> proposal.get(${t?.id}) failed`),e.setError(p.EVENT_CLIENT_SESSION_ERRORS.proposal_not_found),f}try{await this.isValidApprove(t)}catch(f){throw this.client.logger.error("approve() -> isValidApprove() failed"),e.setError(p.EVENT_CLIENT_SESSION_ERRORS.session_approve_namespace_validation_failure),f}const{id:s,relayProtocol:r,namespaces:n,sessionProperties:a,scopedProperties:o,sessionConfig:l,proposalRequestsResponses:h}=t,d=this.client.proposal.get(s);this.client.core.eventClient.deleteEvent({eventId:e.eventId});const{pairingTopic:E,proposer:y,requiredNamespaces:g,optionalNamespaces:w}=d;let u=this.client.core.eventClient?.getEvent({topic:E});u||(u=this.client.core.eventClient?.createEvent({type:p.EVENT_CLIENT_SESSION_TRACES.session_approve_started,properties:{topic:E,trace:[p.EVENT_CLIENT_SESSION_TRACES.session_approve_started,p.EVENT_CLIENT_SESSION_TRACES.session_namespaces_validation_success]}}));const _=await this.client.core.crypto.generateKeyPair(),T=y.publicKey,I=await this.client.core.crypto.generateSharedKey(_,T),A={relay:{protocol:r??"irn"},namespaces:n,controller:{publicKey:_,metadata:this.client.metadata},expiry:i.calcExpiry(M),...a&&{sessionProperties:a},...o&&{scopedProperties:o},...l&&{sessionConfig:l},proposalRequestsResponses:h},v=p.TRANSPORT_TYPES.relay;u.addTrace(p.EVENT_CLIENT_SESSION_TRACES.subscribing_session_topic);try{await this.client.core.relayer.subscribe(I,{transportType:v,internal:{skipSubscribe:!0}})}catch(f){throw u.setError(p.EVENT_CLIENT_SESSION_ERRORS.subscribe_session_topic_failure),f}u.addTrace(p.EVENT_CLIENT_SESSION_TRACES.subscribe_session_topic_success);const V={...A,topic:I,requiredNamespaces:g,optionalNamespaces:w,pairingTopic:E,acknowledged:!1,self:A.controller,peer:{publicKey:y.publicKey,metadata:y.metadata},controller:_,transportType:p.TRANSPORT_TYPES.relay,authentication:h?.authentication,walletPayResult:h?.walletPay};await this.client.session.set(I,V),u.addTrace(p.EVENT_CLIENT_SESSION_TRACES.store_session);try{await this.sendApproveSession({sessionTopic:I,proposal:d,pairingProposalResponse:{relay:{protocol:r??"irn"},responderPublicKey:_},sessionSettleRequest:A,publishOpts:{internal:{throwOnFailedPublish:!0},tvf:{correlationId:s,...this.getTVFApproveParams(V)}}}),u.addTrace(p.EVENT_CLIENT_SESSION_TRACES.session_approve_publish_success)}catch(f){throw this.client.logger.error(f),this.client.session.delete(I,i.getSdkError("USER_DISCONNECTED")),await this.client.core.relayer.unsubscribe(I),f}return this.client.core.eventClient.deleteEvent({eventId:u.eventId}),await this.client.core.pairing.updateMetadata({topic:E,metadata:y.metadata}),await this.deleteProposal(s),await this.client.core.pairing.activate({topic:E}),await this.setExpiry(I,i.calcExpiry(M)),{topic:I,acknowledged:()=>Promise.resolve(this.client.session.get(I))}},this.reject=async t=>{this.isInitialized(),await this.confirmOnlineStateOrThrow();try{await this.isValidReject(t)}catch(n){throw this.client.logger.error("reject() -> isValidReject() failed"),n}const{id:e,reason:s}=t;let r;try{r=this.client.proposal.get(e).pairingTopic}catch(n){throw this.client.logger.error(`reject() -> proposal.get(${e}) failed`),n}r&&await this.sendError({id:e,topic:r,error:s,rpcOpts:N.wc_sessionPropose.reject}),await this.deleteProposal(e)},this.update=async t=>{this.isInitialized(),await this.confirmOnlineStateOrThrow();try{await this.isValidUpdate(t)}catch(d){throw this.client.logger.error("update() -> isValidUpdate() failed"),d}const{topic:e,namespaces:s}=t,{done:r,resolve:n,reject:a}=i.createDelayedPromise(S.FIVE_MINUTES,"Session update request expired without receiving any acknowledgement"),o=m.payloadId(),l=m.getBigIntRpcId().toString(),h=this.client.session.get(e).namespaces;return this.events.once(i.engineEvent("session_update",o),({error:d})=>{d?a(d):n()}),await this.client.session.update(e,{namespaces:s}),await this.sendRequest({topic:e,method:"wc_sessionUpdate",params:{namespaces:s},throwOnFailedPublish:!0,clientRpcId:o,relayRpcId:l}).catch(d=>{this.client.logger.error(d),this.client.session.update(e,{namespaces:h}),a(d)}),{acknowledged:r}},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=m.payloadId(),{done:r,resolve:n,reject:a}=i.createDelayedPromise(S.FIVE_MINUTES,"Session extend request expired without receiving any acknowledgement");return this.events.once(i.engineEvent("session_extend",s),({error:o})=>{o?a(o):n()}),await this.setExpiry(e,i.calcExpiry(M)),this.sendRequest({topic:e,method:"wc_sessionExtend",params:{},clientRpcId:s,throwOnFailedPublish:!0}).catch(o=>{a(o)}),{acknowledged:r}},this.request=async t=>{this.isInitialized();try{await this.isValidRequest(t)}catch(u){throw this.client.logger.error("request() -> isValidRequest() failed"),u}const{chainId:e,request:s,topic:r,expiry:n=N.wc_sessionRequest.req.ttl}=t,a=this.client.session.get(r);a?.transportType===p.TRANSPORT_TYPES.relay&&await this.confirmOnlineStateOrThrow();const o=m.payloadId(),l=m.getBigIntRpcId().toString(),{done:h,resolve:d,reject:E}=i.createDelayedPromise(n,"Request expired. Please try again.");this.events.once(i.engineEvent("session_request",o),({error:u,result:_})=>{u?E(u):d(_)});const y="wc_sessionRequest",g=this.getAppLinkIfEnabled(a.peer.metadata,a.transportType);if(g)return await this.sendRequest({clientRpcId:o,relayRpcId:l,topic:r,method:y,params:{request:{...s,expiryTimestamp:i.calcExpiry(n)},chainId:e},expiry:n,throwOnFailedPublish:!0,appLink:g}).catch(u=>E(u)),this.client.events.emit("session_request_sent",{topic:r,request:s,chainId:e,id:o}),await h();const w={request:{...s,expiryTimestamp:i.calcExpiry(n)},chainId:e};return await Promise.all([new Promise(async u=>{await this.sendRequest({clientRpcId:o,relayRpcId:l,topic:r,method:y,params:w,expiry:n,throwOnFailedPublish:!0,tvf:this.getTVFParams(o,w)}).catch(_=>E(_)),this.client.events.emit("session_request_sent",{topic:r,request:s,chainId:e,id:o}),u()}),new Promise(async u=>{if(!a.sessionConfig?.disableDeepLink){const _=await i.getDeepLink(this.client.core.storage,ne);await i.handleDeeplinkRedirect({id:o,topic:r,wcDeepLink:_})}u()}),h()]).then(u=>u[2])},this.respond=async t=>{this.isInitialized();const e=this.client.core.eventClient.createEvent({properties:{topic:t?.topic||t?.response?.id?.toString(),trace:[p.EVENT_CLIENT_SESSION_TRACES.session_request_response_started]}});try{await this.isValidRespond(t)}catch(l){throw e.addTrace(l?.message),e.setError(p.EVENT_CLIENT_SESSION_ERRORS.session_request_response_validation_failure),l}e.addTrace(p.EVENT_CLIENT_SESSION_TRACES.session_request_response_validation_success);const{topic:s,response:r}=t,{id:n}=r,a=this.client.session.get(s);a.transportType===p.TRANSPORT_TYPES.relay&&await this.confirmOnlineStateOrThrow();const o=this.getAppLinkIfEnabled(a.peer.metadata,a.transportType);try{e.addTrace(p.EVENT_CLIENT_SESSION_TRACES.session_request_response_publish_started),m.isJsonRpcResult(r)?await this.sendResult({id:n,topic:s,result:r.result,throwOnFailedPublish:!0,appLink:o}):m.isJsonRpcError(r)&&await this.sendError({id:n,topic:s,error:r.error,appLink:o}),this.cleanupAfterResponse(t)}catch(l){throw e.addTrace(l?.message),e.setError(p.EVENT_CLIENT_SESSION_ERRORS.session_request_response_publish_failure),l}},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=m.payloadId(),r=m.getBigIntRpcId().toString(),{done:n,resolve:a,reject:o}=i.createDelayedPromise(S.FIVE_MINUTES,"Ping request expired without receiving any acknowledgement");this.events.once(i.engineEvent("session_ping",s),({error:l})=>{l?o(l):a()}),await Promise.all([this.sendRequest({topic:e,method:"wc_sessionPing",params:{},throwOnFailedPublish:!0,clientRpcId:s,relayRpcId:r}),n()])}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:r}=t,n=m.getBigIntRpcId().toString(),a=m.payloadId();await this.sendRequest({topic:e,method:"wc_sessionEvent",params:{event:s,chainId:r},throwOnFailedPublish:!0,relayRpcId:n,clientRpcId:a})},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:i.getSdkError("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}=i.getInternalError("MISMATCHED_TOPIC",`Session or pairing topic not found: ${e}`);throw new Error(s)}},this.find=t=>(this.isInitialized(),this.client.session.getAll().filter(e=>i.isSessionCompatible(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,r=s?p.TRANSPORT_TYPES.link_mode:p.TRANSPORT_TYPES.relay;r===p.TRANSPORT_TYPES.relay&&await this.confirmOnlineStateOrThrow();const{chains:n,statement:a="",uri:o,domain:l,nonce:h,type:d,exp:E,nbf:y,methods:g=[],expiry:w}=t,u=[...t.resources||[]],{topic:_,uri:T}=await this.client.core.pairing.create({methods:["wc_sessionAuthenticate"],transportType:r});this.client.logger.info({message:"Generated new pairing",pairing:{topic:_,uri:T}});const I=await this.client.core.crypto.generateKeyPair(),A=i.hashKey(I);if(await Promise.all([this.client.auth.authKeys.set(H,{responseTopic:A,publicKey:I}),this.client.auth.pairingTopics.set(A,{topic:A,pairingTopic:_})]),await this.client.core.relayer.subscribe(A,{transportType:r}),this.client.logger.info(`sending request to new pairing topic: ${_}`),g.length>0){const{namespace:P}=i.parseChainId(n[0]);let q=i.createEncodedRecap(P,"request",g);i.getRecapFromResources(u)&&(q=i.mergeEncodedRecaps(q,u.pop())),u.push(q)}const v=w&&w>N.wc_sessionAuthenticate.req.ttl?w:N.wc_sessionAuthenticate.req.ttl,V={authPayload:{type:d??"caip122",chains:n,statement:a,aud:o,domain:l,version:"1",nonce:h,iat:new Date().toISOString(),exp:E,nbf:y,resources:u},requester:{publicKey:I,metadata:this.client.metadata},expiryTimestamp:i.calcExpiry(v)},f={eip155:{chains:n,methods:[...new Set(["personal_sign",...g])],events:["chainChanged","accountsChanged"]}},R={requiredNamespaces:{},optionalNamespaces:f,relays:[{protocol:"irn"}],pairingTopic:_,proposer:{publicKey:I,metadata:this.client.metadata},expiryTimestamp:i.calcExpiry(N.wc_sessionPropose.req.ttl),id:m.payloadId()},{done:x,resolve:j,reject:U}=i.createDelayedPromise(v,"Request expired"),L=m.payloadId(),D=i.engineEvent("session_connect",R.id),$=i.engineEvent("session_request",L),k=async({error:P,session:q})=>{this.events.off($,F),P?U(P):q&&j({session:q})},F=async P=>{if(await this.deletePendingAuthRequest(L,{message:"fulfilled",code:0}),P.error){const G=i.getSdkError("WC_METHOD_UNSUPPORTED","wc_sessionAuthenticate");return P.error.code===G.code?void 0:(this.events.off(D,k),U(P.error.message))}await this.deleteProposal(R.id),this.events.off(D,k);const{cacaos:q,responder:b}=P.result,W=[],oe=[];for(const G of q){await i.validateSignedCacao({cacao:G,projectId:this.client.core.projectId})||(this.client.logger.error(G,"Signature verification failed"),U(i.getSdkError("SESSION_SETTLEMENT_FAILED","Signature verification failed")));const{p:Z}=G,ee=i.getRecapFromResources(Z.resources),ce=[i.getNamespacedDidChainId(Z.iss)],fe=i.getDidAddress(Z.iss);if(ee){const te=i.getMethodsFromRecap(ee),Pe=i.getChainsFromRecap(ee);W.push(...te),ce.push(...Pe)}for(const te of ce)oe.push(`${te}:${fe}`)}const K=await this.client.core.crypto.generateSharedKey(I,b.publicKey);let Q;W.length>0&&(Q={topic:K,acknowledged:!0,self:{publicKey:I,metadata:this.client.metadata},peer:b,controller:b.publicKey,expiry:i.calcExpiry(M),requiredNamespaces:{},optionalNamespaces:{},relay:{protocol:"irn"},pairingTopic:_,namespaces:i.buildNamespacesFromAuth([...new Set(W)],[...new Set(oe)]),transportType:r},await this.client.core.relayer.subscribe(K,{transportType:r}),await this.client.session.set(K,Q),_&&await this.client.core.pairing.updateMetadata({topic:_,metadata:b.metadata}),Q=this.client.session.get(K)),this.client.metadata.redirect?.linkMode&&b.metadata.redirect?.linkMode&&b.metadata.redirect?.universal&&e&&(this.client.core.addLinkModeSupportedApp(b.metadata.redirect.universal),this.client.session.update(K,{transportType:p.TRANSPORT_TYPES.link_mode})),j({auths:q,session:Q})};this.events.once(D,k),this.events.once($,F);let J;try{if(s){const P=m.formatJsonRpcRequest("wc_sessionAuthenticate",V,L);this.client.core.history.set(_,P);const q=await this.client.core.crypto.encode("",P,{type:i.TYPE_2,encoding:i.BASE64URL});J=i.getLinkModeURL(e,_,q)}else await Promise.all([this.sendRequest({topic:_,method:"wc_sessionAuthenticate",params:V,expiry:t.expiry,throwOnFailedPublish:!0,clientRpcId:L}),this.sendRequest({topic:_,method:"wc_sessionPropose",params:R,expiry:N.wc_sessionPropose.req.ttl,throwOnFailedPublish:!0,clientRpcId:R.id})])}catch(P){throw this.events.off(D,k),this.events.off($,F),P}return await this.setProposal(R.id,R),await this.setAuthRequest(L,{request:{...V,verifyContext:{}},pairingTopic:_,transportType:r}),{uri:J??T,response:x}},this.approveSessionAuthenticate=async t=>{const{id:e,auths:s}=t,r=this.client.core.eventClient.createEvent({properties:{topic:e.toString(),trace:[p.EVENT_CLIENT_AUTHENTICATE_TRACES.authenticated_session_approve_started]}});try{this.isInitialized()}catch(u){throw r.setError(p.EVENT_CLIENT_AUTHENTICATE_ERRORS.no_internet_connection),u}const n=this.getPendingAuthRequest(e);if(!n)throw r.setError(p.EVENT_CLIENT_AUTHENTICATE_ERRORS.authenticated_session_pending_request_not_found),new Error(`Could not find pending auth request with id ${e}`);const a=n.transportType||p.TRANSPORT_TYPES.relay;a===p.TRANSPORT_TYPES.relay&&await this.confirmOnlineStateOrThrow();const o=n.requester.publicKey,l=await this.client.core.crypto.generateKeyPair(),h=i.hashKey(o),d={type:i.TYPE_1,receiverPublicKey:o,senderPublicKey:l},E=[],y=[];for(const u of s){if(!await i.validateSignedCacao({cacao:u,projectId:this.client.core.projectId})){r.setError(p.EVENT_CLIENT_AUTHENTICATE_ERRORS.invalid_cacao);const v=i.getSdkError("SESSION_SETTLEMENT_FAILED","Signature verification failed");throw await this.sendError({id:e,topic:h,error:v,encodeOpts:d}),new Error(v.message)}r.addTrace(p.EVENT_CLIENT_AUTHENTICATE_TRACES.cacaos_verified);const{p:_}=u,T=i.getRecapFromResources(_.resources),I=[i.getNamespacedDidChainId(_.iss)],A=i.getDidAddress(_.iss);if(T){const v=i.getMethodsFromRecap(T),V=i.getChainsFromRecap(T);E.push(...v),I.push(...V)}for(const v of I)y.push(`${v}:${A}`)}const g=await this.client.core.crypto.generateSharedKey(l,o);r.addTrace(p.EVENT_CLIENT_AUTHENTICATE_TRACES.create_authenticated_session_topic);let w;if(E?.length>0){w={topic:g,acknowledged:!0,self:{publicKey:l,metadata:this.client.metadata},peer:{publicKey:o,metadata:n.requester.metadata},controller:o,expiry:i.calcExpiry(M),authentication:s,requiredNamespaces:{},optionalNamespaces:{},relay:{protocol:"irn"},pairingTopic:n.pairingTopic,namespaces:i.buildNamespacesFromAuth([...new Set(E)],[...new Set(y)]),transportType:a},r.addTrace(p.EVENT_CLIENT_AUTHENTICATE_TRACES.subscribing_authenticated_session_topic);try{await this.client.core.relayer.subscribe(g,{transportType:a})}catch(u){throw r.setError(p.EVENT_CLIENT_AUTHENTICATE_ERRORS.subscribe_authenticated_session_topic_failure),u}r.addTrace(p.EVENT_CLIENT_AUTHENTICATE_TRACES.subscribe_authenticated_session_topic_success),await this.client.session.set(g,w),r.addTrace(p.EVENT_CLIENT_AUTHENTICATE_TRACES.store_authenticated_session),await this.client.core.pairing.updateMetadata({topic:n.pairingTopic,metadata:n.requester.metadata})}r.addTrace(p.EVENT_CLIENT_AUTHENTICATE_TRACES.publishing_authenticated_session_approve);try{await this.sendResult({topic:h,id:e,result:{cacaos:s,responder:{publicKey:l,metadata:this.client.metadata}},encodeOpts:d,throwOnFailedPublish:!0,appLink:this.getAppLinkIfEnabled(n.requester.metadata,a)})}catch(u){throw r.setError(p.EVENT_CLIENT_AUTHENTICATE_ERRORS.authenticated_session_approve_publish_failure),u}return await this.client.auth.requests.delete(e,{message:"fulfilled",code:0}),await this.client.core.pairing.activate({topic:n.pairingTopic}),this.client.core.eventClient.deleteEvent({eventId:r.eventId}),{session:w}},this.rejectSessionAuthenticate=async t=>{this.isInitialized();const{id:e,reason:s}=t,r=this.getPendingAuthRequest(e);if(!r)throw new Error(`Could not find pending auth request with id ${e}`);r.transportType===p.TRANSPORT_TYPES.relay&&await this.confirmOnlineStateOrThrow();const n=r.requester.publicKey,a=await this.client.core.crypto.generateKeyPair(),o=i.hashKey(n),l={type:i.TYPE_1,receiverPublicKey:n,senderPublicKey:a};await this.sendError({id:e,topic:o,error:s,encodeOpts:l,rpcOpts:N.wc_sessionAuthenticate.reject,appLink:this.getAppLinkIfEnabled(r.requester.metadata,r.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 i.formatMessage(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(r=>r.peerMetadata?.url&&r.peerMetadata?.url===t.peer.metadata.url&&r.topic&&r.topic!==e.topic);if(s.length===0)return;this.client.logger.info(`Cleaning up ${s.length} duplicate pairing(s)`),await Promise.all(s.map(r=>this.client.core.pairing.disconnect({topic:r.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:r=!0,id:n=0}=t,{self:a}=this.client.session.get(e);await this.client.core.relayer.unsubscribe(e),await this.client.session.delete(e,i.getSdkError("USER_DISCONNECTED")),this.addToRecentlyDeleted(e,"session"),this.client.core.crypto.keychain.has(a.publicKey)&&await this.client.core.crypto.deleteKeyPair(a.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(ne).catch(o=>this.client.logger.warn(o)),e===this.sessionRequestQueue.queue[0]?.topic&&(this.sessionRequestQueue.state=C.idle),await Promise.all(this.getPendingSessionRequests().filter(o=>o.topic===e).map(o=>this.deletePendingSessionRequest(o.id,i.getSdkError("USER_DISCONNECTED")))),r&&this.client.events.emit("session_delete",{id:n,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(p.EVENT_CLIENT_SESSION_ERRORS.proposal_expired)}catch{}await Promise.all([this.client.proposal.delete(t,i.getSdkError("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(r=>r.id!==t),s&&(this.sessionRequestQueue.state=C.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,i.calcExpiry(N.wc_sessionPropose.req.ttl)),await this.client.proposal.set(t,e)},this.setAuthRequest=async(t,e)=>{const{request:s,pairingTopic:r,transportType:n=p.TRANSPORT_TYPES.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:r,verifyContext:s.verifyContext,transportType:n})},this.setPendingSessionRequest=async t=>{const{id:e,topic:s,params:r,verifyContext:n}=t,a=r.request.expiryTimestamp||i.calcExpiry(N.wc_sessionRequest.req.ttl);this.client.core.expirer.set(e,a),await this.client.pendingRequest.set(e,{id:e,topic:s,params:r,verifyContext:n})},this.sendRequest=async t=>{const{topic:e,method:s,params:r,expiry:n,relayRpcId:a,clientRpcId:o,throwOnFailedPublish:l,appLink:h,tvf:d,publishOpts:E={}}=t,y=m.formatJsonRpcRequest(s,r,o);let g;const w=!!h;try{const T=w?i.BASE64URL:i.BASE64;g=await this.client.core.crypto.encode(e,y,{encoding:T})}catch(T){throw await this.cleanup(),this.client.logger.error(`sendRequest() -> core.crypto.encode() for topic ${e} failed`),T}let u;if(ye.includes(s)){const T=i.hashMessage(JSON.stringify(y)),I=i.hashMessage(g);u=await this.client.core.verify.register({id:I,decryptedId:T})}const _={...N[s].req,...E};if(_.attestation=u,n&&(_.ttl=n),a&&(_.id=a),this.client.core.history.set(e,y),w){const T=i.getLinkModeURL(h,e,g);await global.Linking.openURL(T,this.client.name)}else _.tvf={...d,correlationId:y.id},l?(_.internal={..._.internal,throwOnFailedPublish:!0},await this.client.core.relayer.publish(e,g,_)):this.client.core.relayer.publish(e,g,_).catch(T=>this.client.logger.error(T));return y.id},this.sendProposeSession=async t=>{const{proposal:e,publishOpts:s}=t,r=m.formatJsonRpcRequest("wc_sessionPropose",e,e.id);this.client.core.history.set(e.pairingTopic,r);const n=await this.client.core.crypto.encode(e.pairingTopic,r,{encoding:i.BASE64}),a=i.hashMessage(JSON.stringify(r)),o=i.hashMessage(n),l=await this.client.core.verify.register({id:o,decryptedId:a});await this.client.core.relayer.publishCustom({payload:{pairingTopic:e.pairingTopic,sessionProposal:n},opts:{...s,publishMethod:"wc_proposeSession",attestation:l}})},this.sendApproveSession=async t=>{const{sessionTopic:e,pairingProposalResponse:s,proposal:r,sessionSettleRequest:n,publishOpts:a}=t,o=m.formatJsonRpcResult(r.id,s),l=await this.client.core.crypto.encode(r.pairingTopic,o,{encoding:i.BASE64}),h=m.formatJsonRpcRequest("wc_sessionSettle",n,a?.id),d=await this.client.core.crypto.encode(e,h,{encoding:i.BASE64});this.client.core.history.set(e,h),await this.client.core.relayer.publishCustom({payload:{sessionTopic:e,pairingTopic:r.pairingTopic,sessionProposalResponse:l,sessionSettlementRequest:d},opts:{...a,publishMethod:"wc_approveSession"}})},this.sendResult=async t=>{const{id:e,topic:s,result:r,throwOnFailedPublish:n,encodeOpts:a,appLink:o}=t,l=m.formatJsonRpcResult(e,r);let h;const d=o&&typeof global?.Linking<"u";try{const g=d?i.BASE64URL:i.BASE64;h=await this.client.core.crypto.encode(s,l,{...a||{},encoding:g})}catch(g){throw await this.cleanup(),this.client.logger.error(`sendResult() -> core.crypto.encode() for topic ${s} failed`),g}let E,y;try{E=await this.client.core.history.get(s,e);const g=E.request;try{y=this.getTVFParams(e,g.params,r)}catch(w){this.client.logger.warn(`sendResult() -> getTVFParams() failed: ${w?.message}`)}}catch(g){throw this.client.logger.error(`sendResult() -> history.get(${s}, ${e}) failed`),g}if(d){const g=i.getLinkModeURL(o,s,h);await global.Linking.openURL(g,this.client.name)}else{const g=E.request.method,w=N[g].res;w.tvf={...y,correlationId:e},n?(w.internal={...w.internal,throwOnFailedPublish:!0},await this.client.core.relayer.publish(s,h,w)):this.client.core.relayer.publish(s,h,w).catch(u=>this.client.logger.error(u))}await this.client.core.history.resolve(l)},this.sendError=async t=>{const{id:e,topic:s,error:r,encodeOpts:n,rpcOpts:a,appLink:o}=t,l=m.formatJsonRpcError(e,r);let h;const d=o&&typeof global?.Linking<"u";try{const y=d?i.BASE64URL:i.BASE64;h=await this.client.core.crypto.encode(s,l,{...n||{},encoding:y})}catch(y){throw await this.cleanup(),this.client.logger.error(`sendError() -> core.crypto.encode() for topic ${s} failed`),y}let E;try{E=await this.client.core.history.get(s,e)}catch(y){throw this.client.logger.error(`sendError() -> history.get(${s}, ${e}) failed`),y}if(d){const y=i.getLinkModeURL(o,s,h);await global.Linking.openURL(y,this.client.name)}else{const y=E.request.method,g=a||N[y].res;this.client.core.relayer.publish(s,h,g)}await this.client.core.history.resolve(l)},this.cleanup=async()=>{const t=[],e=[];this.client.session.getAll().forEach(s=>{let r=!1;i.isExpired(s.expiry)&&(r=!0),this.client.core.crypto.keychain.has(s.topic)||(r=!0),r&&t.push(s.topic)}),this.client.proposal.getAll().forEach(s=>{i.isExpired(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===C.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=C.active;const t=this.requestQueue.queue.shift();if(t)try{await this.processRequest(t)}catch(e){this.client.logger.warn(e)}}this.requestQueue.state=C.idle},this.processRequest=async t=>{const{topic:e,payload:s,attestation:r,transportType:n,encryptedId:a}=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:r,encryptedId:a});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:r,encryptedId:a,transportType:n});case"wc_sessionEvent":return await this.onSessionEventRequest(e,s);case"wc_sessionAuthenticate":return await this.onSessionAuthenticateRequest({topic:e,payload:s,attestation:r,encryptedId:a,transportType:n});default:return this.client.logger.info(`Unsupported request method ${o}`)}},this.onRelayEventResponse=async t=>{const{topic:e,payload:s,transportType:r}=t,n=(await this.client.core.history.get(e,s.id)).request.method;switch(n){case"wc_sessionPropose":return this.onSessionProposeResponse(e,s,r);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 ${n}`)}},this.onRelayEventUnknownPayload=t=>{const{topic:e}=t,{message:s}=i.getInternalError("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,r=this.expectedPairingMethodMap.get(e);return!r||r.includes(s)?!1:!!(r.includes("wc_sessionAuthenticate")&&this.client.events.listenerCount("session_authenticate")>0)},this.onSessionProposeRequest=async t=>{const{topic:e,payload:s,attestation:r,encryptedId:n}=t,{params:a,id:o}=s;try{const l=this.client.core.eventClient.getEvent({topic:e});this.client.events.listenerCount("session_proposal")===0&&(console.warn("No listener for session_proposal event"),l?.setError(p.EVENT_CLIENT_PAIRING_ERRORS.proposal_listener_not_found)),this.isValidConnect({...s.params});const h=a.expiryTimestamp||i.calcExpiry(N.wc_sessionPropose.req.ttl),d={id:o,pairingTopic:e,expiryTimestamp:h,attestation:r,encryptedId:n,...a};await this.setProposal(o,d);const E=await this.getVerifyContext({attestationId:r,hash:i.hashMessage(JSON.stringify(s)),encryptedId:n,metadata:d.proposer.metadata});l?.addTrace(p.EVENT_CLIENT_PAIRING_TRACES.emit_session_proposal),this.client.events.emit("session_proposal",{id:o,params:d,verifyContext:E})}catch(l){await this.sendError({id:o,topic:e,error:l,rpcOpts:N.wc_sessionPropose.autoReject}),this.client.logger.error(l)}},this.onSessionProposeResponse=async(t,e,s)=>{const{id:r}=e;if(m.isJsonRpcResult(e)){const{result:n}=e;this.client.logger.trace({type:"method",method:"onSessionProposeResponse",result:n});const a=this.client.proposal.get(r);this.client.logger.trace({type:"method",method:"onSessionProposeResponse",proposal:a});const o=a.proposer.publicKey;this.client.logger.trace({type:"method",method:"onSessionProposeResponse",selfPublicKey:o});const l=n.responderPublicKey;this.client.logger.trace({type:"method",method:"onSessionProposeResponse",peerPublicKey:l});const h=await this.client.core.crypto.generateSharedKey(o,l);this.pendingSessions.set(r,{sessionTopic:h,pairingTopic:t,proposalId:r,publicKey:o});const d=await this.client.core.relayer.subscribe(h,{transportType:s});this.client.logger.trace({type:"method",method:"onSessionProposeResponse",subscriptionId:d}),await this.client.core.pairing.activate({topic:t})}else if(m.isJsonRpcError(e)){await this.deleteProposal(r);const n=i.engineEvent("session_connect",r);if(this.events.listenerCount(n)===0)throw new Error(`emitting ${n} without any listeners, 954`);this.events.emit(n,{error:e.error})}},this.onSessionSettleRequest=async(t,e)=>{const{id:s,params:r}=e;try{this.isValidSessionSettleRequest(r);const{relay:n,controller:a,expiry:o,namespaces:l,sessionProperties:h,scopedProperties:d,sessionConfig:E,proposalRequestsResponses:y}=e.params,g=[...this.pendingSessions.values()].find(_=>_.sessionTopic===t);if(!g)return this.client.logger.error(`Pending session not found for topic ${t}`);const w=this.client.proposal.get(g.proposalId),u={topic:t,relay:n,expiry:o,namespaces:l,acknowledged:!0,pairingTopic:g.pairingTopic,requiredNamespaces:w.requiredNamespaces,optionalNamespaces:w.optionalNamespaces,controller:a.publicKey,self:{publicKey:g.publicKey,metadata:this.client.metadata},peer:{publicKey:a.publicKey,metadata:a.metadata},...h&&{sessionProperties:h},...d&&{scopedProperties:d},...E&&{sessionConfig:E},transportType:p.TRANSPORT_TYPES.relay,authentication:y?.authentication,walletPayResult:y?.walletPay};await this.client.session.set(u.topic,u),await this.setExpiry(u.topic,u.expiry),await this.client.core.pairing.updateMetadata({topic:g.pairingTopic,metadata:u.peer.metadata}),this.pendingSessions.delete(g.proposalId),this.deleteProposal(g.proposalId,!1),this.cleanupDuplicatePairings(u),await this.sendResult({id:e.id,topic:t,throwOnFailedPublish:!0,result:!0}),this.client.events.emit("session_connect",{session:u}),this.events.emit(i.engineEvent("session_connect",g.proposalId),{session:u})}catch(n){await this.sendError({id:s,topic:t,error:n}),this.client.logger.error(n)}},this.onSessionSettleResponse=async(t,e)=>{const{id:s}=e;m.isJsonRpcResult(e)?(await this.client.session.update(t,{acknowledged:!0}),this.events.emit(i.engineEvent("session_approve",s),{})):m.isJsonRpcError(e)&&(await this.client.session.delete(t,i.getSdkError("USER_DISCONNECTED")),this.events.emit(i.engineEvent("session_approve",s),{error:e.error}))},this.onSessionUpdateRequest=async(t,e)=>{const{params:s,id:r}=e;try{const n=`${t}_session_update`,a=i.MemoryStore.get(n);if(a&&this.isRequestOutOfSync(a,r)){this.client.logger.warn(`Discarding out of sync request - ${r}`),this.sendError({id:r,topic:t,error:i.getSdkError("INVALID_UPDATE_REQUEST")});return}this.isValidUpdate({topic:t,...s});try{i.MemoryStore.set(n,r),await this.client.session.update(t,{namespaces:s.namespaces}),await this.sendResult({id:r,topic:t,result:!0})}catch(o){throw i.MemoryStore.delete(n),o}this.client.events.emit("session_update",{id:r,topic:t,params:s})}catch(n){await this.sendError({id:r,topic:t,error:n}),this.client.logger.error(n)}},this.isRequestOutOfSync=(t,e)=>e.toString().slice(0,-3)<t.toString().slice(0,-3),this.onSessionUpdateResponse=(t,e)=>{const{id:s}=e,r=i.engineEvent("session_update",s);if(this.events.listenerCount(r)===0)throw new Error(`emitting ${r} without any listeners`);m.isJsonRpcResult(e)?this.events.emit(i.engineEvent("session_update",s),{}):m.isJsonRpcError(e)&&this.events.emit(i.engineEvent("session_update",s),{error:e.error})},this.onSessionExtendRequest=async(t,e)=>{const{id:s}=e;try{this.isValidExtend({topic:t}),await this.setExpiry(t,i.calcExpiry(M)),await this.sendResult({id:s,topic:t,result:!0}),this.client.events.emit("session_extend",{id:s,topic:t})}catch(r){await this.sendError({id:s,topic:t,error:r}),this.client.logger.error(r)}},this.onSessionExtendResponse=(t,e)=>{const{id:s}=e,r=i.engineEvent("session_extend",s);if(this.events.listenerCount(r)===0)throw new Error(`emitting ${r} without any listeners`);m.isJsonRpcResult(e)?this.events.emit(i.engineEvent("session_extend",s),{}):m.isJsonRpcError(e)&&this.events.emit(i.engineEvent("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(r){await this.sendError({id:s,topic:t,error:r}),this.client.logger.error(r)}},this.onSessionPingResponse=(t,e)=>{const{id:s}=e,r=i.engineEvent("session_ping",s);setTimeout(()=>{if(this.events.listenerCount(r)===0)throw new Error(`emitting ${r} without any listeners 2176`);m.isJsonRpcResult(e)?this.events.emit(i.engineEvent("session_ping",s),{}):m.isJsonRpcError(e)&&this.events.emit(i.engineEvent("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:i.getSdkError("USER_DISCONNECTED")}),await this.deleteSession({topic:t,id:s})}catch(r){this.client.logger.error(r)}},this.onSessionRequest=async t=>{const{topic:e,payload:s,attestation:r,encryptedId:n,transportType:a}=t,{id:o,params:l}=s;try{await this.isValidRequest({topic:e,...l});const h=this.client.session.get(e),d=await this.getVerifyContext({attestationId:r,hash:i.hashMessage(JSON.stringify(m.formatJsonRpcRequest("wc_sessionRequest",l,o))),encryptedId:n,metadata:h.peer.metadata,transportType:a}),E={id:o,topic:e,params:l,verifyContext:d};await this.setPendingSessionRequest(E),a===p.TRANSPORT_TYPES.link_mode&&h.peer.metadata.redirect?.universal&&this.client.core.addLinkModeSupportedApp(h.peer.metadata.redirect?.universal),this.client.signConfig?.disableRequestQueue?this.emitSessionRequest(E):(this.addSessionRequestToSessionRequestQueue(E),this.processSessionRequestQueue())}catch(h){await this.sendError({id:o,topic:e,error:h}),this.client.logger.error(h)}},this.onSessionRequestResponse=(t,e)=>{const{id:s}=e,r=i.engineEvent("session_request",s);if(this.events.listenerCount(r)===0)throw new Error(`emitting ${r} without any listeners`);m.isJsonRpcResult(e)?this.events.emit(i.engineEvent("session_request",s),{result:e.result}):m.isJsonRpcError(e)&&this.events.emit(i.engineEvent("session_request",s),{error:e.error})},this.onSessionEventRequest=async(t,e)=>{const{id:s,params:r}=e;try{const n=`${t}_session_event_${r.event.name}`,a=i.MemoryStore.get(n);if(a&&this.isRequestOutOfSync(a,s)){this.client.logger.info(`Discarding out of sync request - ${s}`);return}this.isValidEmit({topic:t,...r}),this.client.events.emit("session_event",{id:s,topic:t,params:r}),i.MemoryStore.set(n,s)}catch(n){await this.sendError({id:s,topic:t,error:n}),this.client.logger.error(n)}},this.onSessionAuthenticateResponse=(t,e)=>{const{id:s}=e;this.client.logger.trace({type:"method",method:"onSessionAuthenticateResponse",topic:t,payload:e}),m.isJsonRpcResult(e)?this.events.emit(i.engineEvent("session_request",s),{result:e.result}):m.isJsonRpcError(e)&&this.events.emit(i.engineEvent("session_request",s),{error:e.error})},this.onSessionAuthenticateRequest=async t=>{const{topic:e,payload:s,attestation:r,encryptedId:n,transportType:a}=t;try{const{requester:o,authPayload:l,expiryTimestamp:h}=s.params,d=await this.getVerifyContext({attestationId:r,hash:i.hashMessage(JSON.stringify(s)),encryptedId:n,metadata:o.metadata,transportType:a}),E={requester:o,pairingTopic:e,id:s.id,authPayload:l,verifyContext:d,expiryTimestamp:h};await this.setAuthRequest(s.id,{request:E,pairingTopic:e,transportType:a}),a===p.TRANSPORT_TYPES.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:d})}catch(o){this.client.logger.error(o);const l=s.params.requester.publicKey,h=await this.client.core.crypto.generateKeyPair(),d=this.getAppLinkIfEnabled(s.params.requester.metadata,a),E={type:i.TYPE_1,receiverPublicKey:l,senderPublicKey:h};await this.sendError({id:s.id,topic:e,error:o,encodeOpts:E,rpcOpts:N.wc_sessionAuthenticate.autoReject,appLink:d})}},this.addSessionRequestToSessionRequestQueue=t=>{this.sessionRequestQueue.queue.push(t)},this.cleanupAfterResponse=t=>{this.deletePendingSessionRequest(t.response.id,{message:"fulfilled",code:0}),setTimeout(()=>{this.sessionRequestQueue.state=C.idle,this.processSessionRequestQueue()},S.toMiliseconds(this.requestQueueDelay))},this.cleanupPendingSentRequestsForTopic=({topic:t,error:e})=>{const s=this.client.core.history.pending;s.length>0&&s.filter(r=>r.topic===t&&r.request.method==="wc_sessionRequest").forEach(r=>{this.events.emit(i.engineEvent("session_request",r.request.id),{error:e})})},this.processSessionRequestQueue=()=>{if(this.sessionRequestQueue.state===C.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=C.active,this.emittedSessionRequests.add(t.id),this.client.events.emit("session_request",t)},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:m.formatJsonRpcRequest("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(!i.isValidParams(t)){const{message:l}=i.getInternalError("MISSING_OR_INVALID",`connect() params: ${JSON.stringify(t)}`);throw new Error(l)}const{pairingTopic:e,requiredNamespaces:s,optionalNamespaces:r,sessionProperties:n,scopedProperties:a,relays:o}=t;if(i.isUndefined(e)||await this.isValidPairingTopic(e),!i.isValidRelays(o,!0)){const{message:l}=i.getInternalError("MISSING_OR_INVALID",`connect() relays: ${o}`);throw new Error(l)}if(s&&!i.isUndefined(s)&&i.isValidObject(s)!==0){const l="requiredNamespaces are deprecated and are automatically assigned to optionalNamespaces";["fatal","error","silent"].includes(this.client.logger.level)?console.warn(l):this.client.logger.warn(l),this.validateNamespaces(s,"requiredNamespaces")}if(r&&!i.isUndefined(r)&&i.isValidObject(r)!==0&&this.validateNamespaces(r,"optionalNamespaces"),n&&!i.isUndefined(n)&&this.validateSessionProps(n,"sessionProperties"),a&&!i.isUndefined(a)){this.validateSessionProps(a,"scopedProperties");const l=Object.keys(s||{}).concat(Object.keys(r||{}));if(!Object.keys(a).every(h=>l.includes(h.split(":")[0])))throw new Error(`Scoped properties must be a subset of required/optional namespaces, received: ${JSON.stringify(a)}, required/optional namespaces: ${JSON.stringify(l)}`)}},this.validateNamespaces=(t,e)=>{const s=i.isValidRequiredNamespaces(t,"connect()",e);if(s)throw new Error(s.message)},this.isValidApprove=async t=>{if(!i.isValidParams(t))throw new Error(i.getInternalError("MISSING_OR_INVALID",`approve() params: ${t}`).message);const{id:e,namespaces:s,relayProtocol:r,sessionProperties:n,scopedProperties:a}=t;this.checkRecentlyDeleted(e),await this.isValidProposalId(e);const o=this.client.proposal.get(e),l=i.isValidNamespaces(s,"approve()");if(l)throw new Error(l.message);const h=i.isConformingNamespaces(o.requiredNamespaces,s,"approve()");if(h)throw new Error(h.message);if(!i.isValidString(r,!0)){const{message:d}=i.getInternalError("MISSING_OR_INVALID",`approve() relayProtocol: ${r}`);throw new Error(d)}if(n&&!i.isUndefined(n)&&this.validateSessionProps(n,"sessionProperties"),a&&!i.isUndefined(a)){this.validateSessionProps(a,"scopedProperties");const d=new Set(Object.keys(s));if(!Object.keys(a).every(E=>d.has(E.split(":")[0])))throw new Error(`Scoped properties must be a subset of approved namespaces, received: ${JSON.stringify(a)}, approved namespaces: ${Array.from(d).join(", ")}`)}},this.isValidReject=async t=>{if(!i.isValidParams(t)){const{message:r}=i.getInternalError("MISSING_OR_INVALID",`reject() params: ${t}`);throw new Error(r)}const{id:e,reason:s}=t;if(this.checkRecentlyDeleted(e),await this.isValidProposal