From 2acee7755e2a451bc741bda83e3c09e4ac95065f Mon Sep 17 00:00:00 2001 From: nattb8 Date: Tue, 16 Dec 2025 03:49:44 +0000 Subject: [PATCH 1/6] chore: update game bridge to 2.12.3 --- .../Passport/Runtime/Resources/index.html | 406 +++++++++++++++--- 1 file changed, 356 insertions(+), 50 deletions(-) diff --git a/src/Packages/Passport/Runtime/Resources/index.html b/src/Packages/Passport/Runtime/Resources/index.html index f57c2a52..a542457e 100644 --- a/src/Packages/Passport/Runtime/Resources/index.html +++ b/src/Packages/Passport/Runtime/Resources/index.html @@ -1,4 +1,4 @@ -GameSDK Bridge

Bridge Running

\ No newline at end of file +)[]`,T=e=>e.map(e=>({delegateCall:!0===e.delegateCall,revertOnError:!0===e.revertOnError,gasLimit:e.gasLimit??BigInt(0),target:e.to??h.ZeroAddress,value:e.value??BigInt(0),data:e.data??"0x"})),_=(e,t)=>{let r=(0,h.AbiCoder).defaultAbiCoder().encode(["uint256",E],[e,t]);return(0,h.keccak256)(r)},S=e=>(0,h.AbiCoder).defaultAbiCoder().encode([E],[e]),k=e=>e||0n,I=(e,t)=>{let r=BigInt(e)*2n**96n;return BigInt(t)+r},C=async(e,t,r)=>{try{let a=new h.Contract(t,w.mainModule.abi,e),n=k(r),i=await a.readNonce(n);if("bigint"==typeof i)return I(n,i);throw Error("Unexpected result from contract.nonce() call.")}catch(e){if((0,h.isError)(e,"BAD_DATA"))return BigInt(0);throw e}},R=(e,t,r)=>(0,h.solidityPacked)(["string","uint256","address","bytes32"],["\x19\x01",e,t,r]),P=async(e,t,r,a,n)=>{let i=T(e),s=R(r,a,_(t,i)),o=(0,h.keccak256)(s),c=(0,h.getBytes)(o),f=A({version:1,threshold:1,signers:[{isDynamic:!1,unrecovered:!0,weight:1,signature:`${await n.signMessage(c)}02`}]}),d=new h.Interface(w.mainModule.abi);return d.encodeFunctionData(d.getFunction("execute")??"",[i,t,f])},M=e=>v(`0x0000${e}`),B=(e,t,r)=>{let a=`${e}02`,{signers:n}=M(r);return A({version:1,threshold:2,signers:[...n,{isDynamic:!1,unrecovered:!0,weight:1,signature:a,address:t}].sort((e,t)=>{let r=BigInt(e.address??0),a=BigInt(t.address??0);return r<=a?-1:r===a?0:1})})},j=async(e,t,r,a,n)=>{let i={...e.types};delete i.EIP712Domain;let s=R(r,a,(0,h.TypedDataEncoder).hash(e.domain,i,e.message)),o=(0,h.keccak256)(s),c=(0,h.getBytes)(o);return B(await n.signMessage(c),await n.getAddress(),t)},O=async(e,t,r,a)=>{let n=R(e,a,(0,h.hashMessage)(t)),i=(0,h.keccak256)(n),s=(0,h.getBytes)(i);return r.signMessage(s)},N=e=>`eip155:${e}`,U=class e{config;rpcProvider;auth;constructor({config:e,rpcProvider:t,auth:r}){this.config=e,this.rpcProvider=t,this.auth=r}static getResponsePreview(e){return e.length>100?`${e.substring(0,50)}...${e.substring(e.length-50)}`:e}async postToRelayer(t){let r,a={id:1,jsonrpc:"2.0",...t},n=await this.auth.getUserZkEvm(),i=await fetch(`${this.config.relayerUrl}/v1/transactions`,{method:"POST",headers:{Authorization:`Bearer ${n.accessToken}`,"Content-Type":"application/json"},body:JSON.stringify(a)}),s=await i.text();if(!i.ok){let t=e.getResponsePreview(s);throw Error(`Relayer HTTP error: ${i.status}. Content: "${t}"`)}try{r=JSON.parse(s)}catch(r){let t=e.getResponsePreview(s);throw Error(`Relayer JSON parse error: ${r instanceof Error?r.message:"Unknown error"}. Content: "${t}"`)}if(r.error)throw Error(r.error);return r}getPreferredFeeTokenSymbol(){return this.config.feeTokenSymbol}async ethSendTransaction(e,t){let{chainId:r}=await this.rpcProvider.getNetwork(),a={method:"eth_sendTransaction",params:[{to:e,data:t,chainId:N(Number(r))}]},{result:n}=await this.postToRelayer(a);return n}async imGetTransactionByHash(e){let{result:t}=await this.postToRelayer({method:"im_getTransactionByHash",params:[e]});return t}async imGetFeeOptions(e,t){let{chainId:r}=await this.rpcProvider.getNetwork(),a={method:"im_getFeeOptions",params:[{userAddress:e,data:t,chainId:N(Number(r))}]},{result:n}=await this.postToRelayer(a);return n}async imSignTypedData(e,t){let{chainId:r}=await this.rpcProvider.getNetwork(),a={method:"im_signTypedData",params:[{address:e,eip712Payload:t,chainId:N(Number(r))}]},{result:n}=await this.postToRelayer(a);return n}async imSign(e,t){let{chainId:r}=await this.rpcProvider.getNetwork(),a={method:"im_sign",params:[{address:e,message:t,chainId:N(Number(r))}]},{result:n}=await this.postToRelayer(a);return n}},L=((s=L||{})[s.USER_REJECTED_REQUEST=4001]="USER_REJECTED_REQUEST",s[s.UNAUTHORIZED=4100]="UNAUTHORIZED",s[s.UNSUPPORTED_METHOD=4200]="UNSUPPORTED_METHOD",s[s.DISCONNECTED=4900]="DISCONNECTED",s),F=((o=F||{})[o.RPC_SERVER_ERROR=-32e3]="RPC_SERVER_ERROR",o[o.INVALID_REQUEST=-32600]="INVALID_REQUEST",o[o.METHOD_NOT_FOUND=-32601]="METHOD_NOT_FOUND",o[o.INVALID_PARAMS=-32602]="INVALID_PARAMS",o[o.INTERNAL_ERROR=-32603]="INTERNAL_ERROR",o[o.PARSE_ERROR=-32700]="PARSE_ERROR",o[o.TRANSACTION_REJECTED=-32003]="TRANSACTION_REJECTED",o),D=class extends Error{message;code;constructor(e,t){super(t),this.message=t,this.code=e}};async function V({auth:e,ethSigner:t,multiRollupApiClients:r,accessToken:a,rpcProvider:n,flow:i}){let s=t.getAddress();s.then(()=>i.addEvent("endGetAddress"));let o=(0,p.signRaw)("Only sign this message from Immutable Passport",t);o.then(()=>i.addEvent("endSignRaw"));let c=n.getNetwork();c.then(()=>i.addEvent("endDetectNetwork"));let f=r.chainsApi.listChains();f.then(()=>i.addEvent("endListChains"));let[d,l,u,h]=await Promise.all([s,o,c,f]),b=N(Number(u.chainId)),g=h.data?.result?.find(e=>e.id===b)?.name;if(!g)throw new D(-32603,`Chain name does not exist on for chain id ${u.chainId}`);try{let t=await r.passportApi.createCounterfactualAddressV2({chainName:g,createCounterfactualAddressRequest:{ethereum_address:d,ethereum_signature:l}},{headers:{Authorization:`Bearer ${a}`}});return i.addEvent("endCreateCounterfactualAddress"),e.forceUserRefreshInBackground(),t.data.counterfactual_address}catch(e){throw new D(-32603,`Failed to create counterfactual address: ${e}`)}}var H="imx_passport_confirmation",q=({url:e,title:t,width:r,height:a})=>{let n=Math.max(0,Math.round(window.screenX+(window.outerWidth-r)/2)),i=Math.max(0,Math.round(window.screenY+(window.outerHeight-a)/2)),s=window.open(e,t,` + scrollbars=yes, + width=${r}, + height=${a}, + top=${i}, + left=${n} + `);if(!s)throw Error("Failed to open confirmation screen");return s.focus(),s},z="passport-overlay",K=`${z}-close`,G=`${z}-try-again`,W=` + + + +`,J=` + + + +`,$=` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`,Z=()=>` + + `,Q=()=>` + +`,X=()=>` + ${$} +
+ ${J} + Pop-up blocked +
+

+ Please try again below.
+ If the problem continues, adjust your
+ browser settings. +

+ ${Q()} + `,Y=()=>` + ${$} +

+ Secure pop-up not showing?
We'll help you re-launch +

+ ${Q()} + `,ee=e=>` +
+ ${Z()} +
+ ${e??""} +
+
+ `;function et({id:e,href:t,rel:r,crossOrigin:a}){let n=`${z}-${e}`;if(!document.getElementById(n)){let e=document.createElement("link");e.id=n,e.href=t,r&&(e.rel=r),a&&(e.crossOrigin=a),document.head.appendChild(e)}}var er,ea=()=>ee(X()),en=()=>ee(Y()),ei=class{disableGenericPopupOverlay;disableBlockedPopupOverlay;overlay;isBlockedOverlay;tryAgainListener;onCloseListener;constructor(e,t=!1){this.disableBlockedPopupOverlay=e.disableBlockedPopupOverlay||!1,this.disableGenericPopupOverlay=e.disableGenericPopupOverlay||!1,this.isBlockedOverlay=t}append(e,t){this.shouldAppendOverlay()&&(this.appendOverlay(),this.updateTryAgainButton(e),this.updateCloseButton(t))}update(e){this.updateTryAgainButton(e)}remove(){this.overlay&&this.overlay.remove()}shouldAppendOverlay(){return!(this.disableGenericPopupOverlay&&this.disableBlockedPopupOverlay||this.disableGenericPopupOverlay&&!this.isBlockedOverlay||this.disableBlockedPopupOverlay&&this.isBlockedOverlay)}appendOverlay(){if(!this.overlay){et({id:"link-googleapis",href:"https://fonts.googleapis.com"}),et({id:"link-gstatic",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"}),et({id:"link-roboto",href:"https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap",rel:"stylesheet"});let e=document.createElement("div");e.innerHTML=this.isBlockedOverlay?ea():en(),document.body.insertAdjacentElement("beforeend",e),this.overlay=e}}updateTryAgainButton(e){let t=document.getElementById(G);t&&(this.tryAgainListener&&t.removeEventListener("click",this.tryAgainListener),this.tryAgainListener=e,t.addEventListener("click",e))}updateCloseButton(e){let t=document.getElementById(K);t&&(this.onCloseListener&&t.removeEventListener("click",this.onCloseListener),this.onCloseListener=e,t.addEventListener("click",e))}},es="Confirm this transaction",eo=class{config;confirmationWindow;popupOptions;overlay;overlayClosed;timer;constructor(e){this.config=e,this.overlayClosed=!1}getHref(e,t){let r=`${this.config.passportDomain}/transaction-confirmation/${e}`;if(t){let e=t?Object.keys(t).map(e=>`${e}=${t[e]}`).join("&"):"";r=`${r}?${e}`}return r}requestConfirmation(e,t,r,a){return new Promise((n,i)=>{let s=({data:e,origin:t})=>{if(!(t!==this.config.passportDomain||e.eventType!==H))switch(e.messageType){case"confirmation_window_ready":this.confirmationWindow?.postMessage({eventType:H,messageType:"confirmation_start"},this.config.passportDomain);break;case"transaction_confirmed":this.closeWindow(),n({confirmed:!0});break;case"transaction_rejected":this.closeWindow(),n({confirmed:!1});break;case"transaction_error":this.closeWindow(),i(Error("Error during transaction confirmation"));break;default:this.closeWindow(),i(Error("Unsupported message type"))}},o="";o=r===l.mr.TransactionApprovalRequestChainTypeEnum.Starkex?this.getHref("transaction",{transactionId:e,etherAddress:t,chainType:r}):this.getHref("zkevm/transaction",{transactionID:e,etherAddress:t,chainType:r,chainID:a}),window.addEventListener("message",s),this.showConfirmationScreen(o,s,n)})}requestMessageConfirmation(e,t,r){return new Promise((a,n)=>{let i=({data:e,origin:t})=>{if(!(t!==this.config.passportDomain||e.eventType!==H))switch(e.messageType){case"confirmation_window_ready":this.confirmationWindow?.postMessage({eventType:H,messageType:"confirmation_start"},this.config.passportDomain);break;case"message_confirmed":this.closeWindow(),a({confirmed:!0});break;case"message_rejected":this.closeWindow(),a({confirmed:!1});break;case"message_error":this.closeWindow(),n(Error("Error during message confirmation"));break;default:this.closeWindow(),n(Error("Unsupported message type"))}};window.addEventListener("message",i);let s=this.getHref("zkevm/message",{messageID:e,etherAddress:t,...r?{messageType:r}:{}});this.showConfirmationScreen(s,i,a)})}showServiceUnavailable(){return new Promise((e,t)=>{this.showConfirmationScreen(this.getHref("unavailable"),()=>{},()=>{this.closeWindow(),t(Error("Service unavailable"))})})}loading(e){if(!this.config.crossSdkBridgeEnabled){this.popupOptions=e;try{this.confirmationWindow=q({url:this.getHref("loading"),title:es,width:e?.width||480,height:e?.height||720}),this.overlay=new ei(this.config.popupOverlayOptions||{})}catch(t){let e=t instanceof Error?t.message:String(t);(0,u.trackError)("passport","confirmationPopupDenied",Error(e)),this.overlay=new ei(this.config.popupOverlayOptions||{},!0)}this.overlay.append(()=>{try{this.confirmationWindow?.close(),this.confirmationWindow=q({url:this.getHref("loading"),title:es,width:this.popupOptions?.width||480,height:this.popupOptions?.height||720})}catch{}},()=>{this.overlayClosed=!0,this.closeWindow()})}}closeWindow(){this.confirmationWindow?.close(),this.overlay?.remove(),this.overlay=void 0}showConfirmationScreen(e,t,r){if(this.confirmationWindow&&(this.confirmationWindow.location.href=e),!this.overlay){this.overlayClosed=!1,r({confirmed:!1});return}let a=()=>{(this.confirmationWindow?.closed||this.overlayClosed)&&(clearInterval(this.timer),window.removeEventListener("message",t),r({confirmed:!1}),this.overlayClosed=!1,this.confirmationWindow=void 0)};this.timer=setInterval(a,1e3),this.overlay.update(()=>this.recreateConfirmationWindow(e,a))}recreateConfirmationWindow(e,t){try{clearInterval(this.timer),this.confirmationWindow?.close(),this.confirmationWindow=q({url:e,title:es,width:this.popupOptions?.width||480,height:this.popupOptions?.height||720}),this.timer=setInterval(t,1e3)}catch{}}},ec=((c=ec||{}).WALLET_CONNECTION_ERROR="WALLET_CONNECTION_ERROR",c.TRANSACTION_REJECTED="TRANSACTION_REJECTED",c.INVALID_CONFIGURATION="INVALID_CONFIGURATION",c.UNAUTHORIZED="UNAUTHORIZED",c.GUARDIAN_ERROR="GUARDIAN_ERROR",c.SERVICE_UNAVAILABLE_ERROR="SERVICE_UNAVAILABLE_ERROR",c.NOT_LOGGED_IN_ERROR="NOT_LOGGED_IN_ERROR",c),ef=class extends Error{type;constructor(e,t){super(e),this.name="WalletError",this.type=t}},ed=e=>"object"==typeof e&&null!==e&&"isAxiosError"in e,el="Transaction requires confirmation but this functionality is not supported in this environment. Please contact Immutable support if you need to enable this feature.",eu=e=>BigInt(e).toString(),eh=e=>{try{return e.map(e=>({delegateCall:!0===e.delegateCall,revertOnError:!0===e.revertOnError,gasLimit:e.gasLimit?eu(e.gasLimit):"0",target:e.to??h.ZeroAddress,value:e.value?eu(e.value):"0",data:e.data?e.data.toString():"0x"}))}catch(t){let e=t instanceof Error?t.message:String(t);throw new D(-32602,`Transaction failed to parsing: ${e}`)}},ep=class{guardianApi;confirmationScreen;crossSdkBridgeEnabled;auth;constructor({config:e,auth:t,guardianApi:r,authConfig:a}){this.confirmationScreen=new eo(a),this.crossSdkBridgeEnabled=e.crossSdkBridgeEnabled,this.guardianApi=r,this.auth=t}withConfirmationScreen(e){return t=>this.withConfirmationScreenTask(e)(t)()}withConfirmationScreenTask(e){return t=>async()=>{this.confirmationScreen.loading(e);try{return await t()}catch(e){throw e instanceof ef&&"SERVICE_UNAVAILABLE_ERROR"===e.type?await this.confirmationScreen.showServiceUnavailable():this.confirmationScreen.closeWindow(),e}}}withDefaultConfirmationScreenTask(e){return this.withConfirmationScreenTask()(e)}async evaluateEVMTransaction({chainId:e,nonce:t,metaTransactions:r}){let a=await this.auth.getUserZkEvm(),n={Authorization:`Bearer ${a.accessToken}`},i=eh(r);try{return(await this.guardianApi.evaluateTransaction({id:"evm",transactionEvaluationRequest:{chainType:"evm",chainId:e,transactionData:{nonce:t,userAddress:a.zkEvm.ethAddress,metaTransactions:i}}},{headers:n})).data}catch(t){if(ed(t)&&t.response?.status===403)throw new ef("Service unavailable","SERVICE_UNAVAILABLE_ERROR");let e=t instanceof Error?t.message:String(t);throw new D(-32603,`Transaction failed to validate with error: ${e}`)}}async validateEVMTransaction({chainId:e,nonce:t,metaTransactions:r,isBackgroundTransaction:a}){let{confirmationRequired:n,transactionId:i}=await this.evaluateEVMTransaction({chainId:e,nonce:t,metaTransactions:r});if(n&&this.crossSdkBridgeEnabled)throw new D(-32003,el);if(n&&i){let t=await this.auth.getUserZkEvm();if(!(await this.confirmationScreen.requestConfirmation(i,t.zkEvm.ethAddress,l.mr.TransactionApprovalRequestChainTypeEnum.Evm,e)).confirmed)throw new D(-32003,"Transaction rejected by user")}else a||this.confirmationScreen.closeWindow()}async handleEIP712MessageEvaluation({chainID:e,payload:t}){try{let r=await this.auth.getUserZkEvm();if(null===r)throw new D(4100,"User not logged in. Please log in first.");return(await this.guardianApi.evaluateMessage({messageEvaluationRequest:{chainID:e,payload:t}},{headers:{Authorization:`Bearer ${r.accessToken}`}})).data}catch(t){let e=t instanceof Error?t.message:String(t);throw new D(-32603,`Message failed to validate with error: ${e}`)}}async evaluateEIP712Message({chainID:e,payload:t}){let{messageId:r,confirmationRequired:a}=await this.handleEIP712MessageEvaluation({chainID:e,payload:t});if(a&&this.crossSdkBridgeEnabled)throw new D(-32003,el);if(a&&r){let e=await this.auth.getUserZkEvm();if(!(await this.confirmationScreen.requestMessageConfirmation(r,e.zkEvm.ethAddress,"eip712")).confirmed)throw new D(-32003,"Signature rejected by user")}else this.confirmationScreen.closeWindow()}async handleERC191MessageEvaluation({chainID:e,payload:t}){try{let r=await this.auth.getUserZkEvm();if(null===r)throw new D(4100,"User not logged in. Please log in first.");return(await this.guardianApi.evaluateErc191Message({eRC191MessageEvaluationRequest:{chainID:N(Number(e)),payload:t}},{headers:{Authorization:`Bearer ${r.accessToken}`}})).data}catch(t){let e=t instanceof Error?t.message:String(t);throw new D(-32603,`Message failed to validate with error: ${e}`)}}async evaluateERC191Message({chainID:e,payload:t}){let{messageId:r,confirmationRequired:a}=await this.handleERC191MessageEvaluation({chainID:e,payload:t});if(a&&this.crossSdkBridgeEnabled)throw new D(-32003,el);if(a&&r){let e=await this.auth.getUserZkEvm();if(!(await this.confirmationScreen.requestMessageConfirmation(r,e.zkEvm.ethAddress,"erc191")).confirmed)throw new D(-32003,"Signature rejected by user")}else this.confirmationScreen.closeWindow()}},eb=e=>new Promise(t=>{setTimeout(()=>t(),e)}),eg=async(e,t)=>{let{retries:r=3,interval:a=1e3,finalErr:n=Error("Retry failed"),finallyFn:i=()=>{}}=t||{};try{return await e()}catch{return r<=0?Promise.reject(n):(await eb(a),eg(e,{retries:r-1,finalErr:n,finallyFn:i}))}finally{r<=0&&i()}},em=async(e,t,r)=>{let a=S(T([e])),n=await r.imGetFeeOptions(t,a);if(!n||!Array.isArray(n))throw Error("Invalid fee options received from relayer");let i=r.getPreferredFeeTokenSymbol(),s=n.find(e=>e.tokenSymbol===i);if(!s)throw Error(`Failed to retrieve fees for ${i} token`);return s},ey=async(e,t,r,a,n)=>{if(!e.to)throw new D(-32602,'eth_sendTransaction requires a "to" field');let i={to:e.to.toString(),data:e.data,nonce:BigInt(0),value:e.value,revertOnError:!0},[s,o]=await Promise.all([C(t,a,n),em(i,a,r)]),c=[{...i,nonce:s}],f=BigInt(o.tokenPrice);return f!==BigInt(0)&&c.push({nonce:s,to:o.recipientAddress,value:f,revertOnError:!0}),c},ex=async(e,t,r)=>{let a=await eg(async()=>{let r=await e.imGetTransactionByHash(t);if("PENDING"===r.status)throw Error();return r},{retries:30,interval:1e3,finalErr:new D(-32e3,"transaction hash not generated in time")});if(r.addEvent("endRetrieveRelayerTransaction"),!["SUBMITTED","SUCCESSFUL"].includes(a.status)){let e=`Transaction failed to submit with status ${a.status}.`;throw a.statusMessage&&(e+=` Error message: ${a.statusMessage}`),new D(-32e3,e)}return a},ew=async({transactionRequest:e,ethSigner:t,rpcProvider:r,guardianClient:a,relayerClient:n,zkEvmAddress:i,flow:s,nonceSpace:o,isBackgroundTransaction:c})=>{let{chainId:f}=await r.getNetwork(),d=BigInt(f);s.addEvent("endDetectNetwork");let l=await ey(e,r,n,i,o);s.addEvent("endBuildMetaTransactions");let{nonce:u}=l[0];if(typeof u>"u")throw Error("Failed to retrieve nonce from the smart wallet");let h=async()=>{await a.validateEVMTransaction({chainId:N(Number(f)),nonce:eu(u),metaTransactions:l,isBackgroundTransaction:c}),s.addEvent("endValidateEVMTransaction")},p=async()=>{let e=await P(l,u,d,i,t);return s.addEvent("endGetSignedMetaTransactions"),e},[,b]=await Promise.all([h(),p()]),g=await n.ethSendTransaction(i,b);return s.addEvent("endRelayerSendTransaction"),{signedTransactions:b,relayerId:g,nonce:u}},ev=async e=>{if(!e.to)throw new D(-32602,'im_signEjectionTransaction requires a "to" field');if(typeof e.nonce>"u")throw new D(-32602,'im_signEjectionTransaction requires a "nonce" field');if(!e.chainId)throw new D(-32602,'im_signEjectionTransaction requires a "chainId" field');return[{to:e.to.toString(),data:e.data,nonce:e.nonce??void 0,value:e.value,revertOnError:!0}]},eA=async({transactionRequest:e,ethSigner:t,zkEvmAddress:r,flow:a})=>{let n=await ev(e);a.addEvent("endBuildMetaTransactions");let i=await P(n,e.nonce,BigInt(e.chainId??0),r,t);return a.addEvent("endGetSignedMetaTransactions"),{to:r,data:i,chainId:N(Number(e.chainId??0))}},eE=async({params:e,ethSigner:t,rpcProvider:r,relayerClient:a,guardianClient:n,zkEvmAddress:i,flow:s,nonceSpace:o,isBackgroundTransaction:c=!1})=>{let f=e[0],{relayerId:d}=await ew({transactionRequest:f,ethSigner:t,rpcProvider:r,guardianClient:n,relayerClient:a,zkEvmAddress:i,flow:s,nonceSpace:o,isBackgroundTransaction:c}),{hash:l}=await ex(a,d,s);return l},eT=["types","domain","primaryType","message"],e_=e=>eT.every(t=>t in e),eS=(e,t)=>{let r;if("string"==typeof e)try{r=JSON.parse(e)}catch(e){throw new D(-32602,`Failed to parse typed data JSON: ${e}`)}else if("object"==typeof e)r=e;else throw new D(-32602,`Invalid typed data argument: ${e}`);if(!e_(r))throw new D(-32602,`Invalid typed data argument. The following properties are required: ${eT.join(", ")}`);let a=r.domain?.chainId;if(a&&("string"==typeof a&&(a.startsWith("0x")?r.domain.chainId=parseInt(a,16).toString():r.domain.chainId=parseInt(a,10).toString()),BigInt(r.domain.chainId??0)!==t))throw new D(-32602,`Invalid chainId, expected ${t}`);return r},ek=async({params:e,method:t,ethSigner:r,rpcProvider:a,relayerClient:n,guardianClient:i,flow:s})=>{let o=e[0],c=e[1];if(!o||!c)throw new D(-32602,`${t} requires an address and a typed data JSON`);let{chainId:f}=await a.getNetwork(),d=eS(c,f);s.addEvent("endDetectNetwork"),await i.evaluateEIP712Message({chainID:String(f),payload:d}),s.addEvent("endValidateMessage");let l=await n.imSignTypedData(o,d);s.addEvent("endRelayerSignTypedData");let u=await j(d,l,BigInt(f),o,r);return s.addEvent("getSignedTypedData"),u},eI=e=>{if(!e)return e;try{let t=(0,h.stripZerosLeft)((0,h.getBytes)(e));return(0,h.toUtf8String)(t)}catch{return e}},eC=async({params:e,ethSigner:t,zkEvmAddress:r,rpcProvider:a,guardianClient:n,relayerClient:i,flow:s})=>{let o=e[0],c=e[1];if(!c||!o)throw new D(-32602,"personal_sign requires an address and a message");if(c.toLowerCase()!==r.toLowerCase())throw new D(-32602,"personal_sign requires the signer to be the from address");let f=eI(o),{chainId:d}=await a.getNetwork();s.addEvent("endDetectNetwork");let l=O(BigInt(d),f,t,c);l.then(()=>s.addEvent("endEOASignature")),await n.evaluateERC191Message({chainID:d,payload:f}),s.addEvent("endEvaluateERC191Message");let[u,h]=await Promise.all([l,i.imSign(c,f)]);s.addEvent("endRelayerSign");let p=await t.getAddress();return s.addEvent("endGetEOAAddress"),B(u,p,h)},eR=e=>{er||(er=e)},eP=e=>{let t=new URL("/v1/sdk/session-activity/check",er);return Object.entries(e).forEach(([e,r])=>{null!=r&&t.searchParams.append(e,String(r))}),t.toString()};async function eM(e){if(!er)throw Error("Client not initialised");let t=await fetch(eP(e));if(404!==t.status){if(!t.ok)throw Error(`Session activity request failed with status ${t.status}`);return t.json()}}var{getItem:eB,setItem:ej}=u.utils.localStorage,eO="sessionActivitySendCount",eN="sessionActivityDate",eU={},eL={},eF={},eD=()=>{eL=eB(eO)||{};let e=eB(eN),t=new Date,r=t.getFullYear(),a=`${t.getMonth()+1}`.padStart(2,"0"),n=`${t.getDate()}`.padStart(2,"0"),i=`${r}-${a}-${n}`;e&&e===i||(eL={}),ej(eN,i),ej(eO,eL)};eD();var eV=e=>{eD(),eL[e]||(eL[e]=0),eL[e]++,ej(eO,eL),eU[e]=0},eH=async e=>new Promise(t=>{setTimeout(t,1e3*e)}),eq=async e=>{let t,r=e.flow||(0,u.trackFlow)("passport","sendSessionActivity"),a=e.passportClient;if(!a)throw r.addEvent("No Passport Client ID"),Error("No Passport Client ID provided");if(eF[a])return;eF[a]=!0;let{sendTransaction:n,sessionActivityApiUrl:i}=e;if(!n)throw Error("No sendTransaction function provided");if(!i)throw Error("No session activity API URL provided");eR(i);let s=e.walletAddress;if(!s)throw r.addEvent("No Passport Wallet Address"),Error("No wallet address");try{if(t=await eM({clientId:a,wallet:s,checkCount:eU[a]||0,sendCount:eL[a]||0}),eU[a]++,!t)return}catch(e){throw r.addEvent("Failed to fetch details"),Error("Failed to get details",{cause:e})}if(t&&t.contractAddress&&t.functionName){let n=new(0,h.Interface)([`function ${t.functionName}()`]).encodeFunctionData(t.functionName),i=t.contractAddress;try{r.addEvent("Start Sending Transaction");let t=await e.sendTransaction([{to:i,from:s,data:n}],r);eV(a),r.addEvent("Transaction Sent",{tx:t})}catch(t){r.addEvent("Failed to send Transaction");let e=Error("Failed to send transaction",{cause:t});(0,u.trackError)("passport","sessionActivityError",e,{flowId:r.details.flowId})}}t&&t.delay&&t.delay>0&&(r.addEvent("Delaying Transaction",{delay:t.delay}),await eH(t.delay),setTimeout(()=>{r.addEvent("Retrying after Delay"),eF[a]=!1,ez({...e,flow:r})},0))},ez=e=>{var t;return((...e)=>{try{let t=eq(...e);return t instanceof Promise?t.catch(e=>void(e instanceof Error&&(0,u.trackError)("passport","sessionActivityError",e))):t}catch(e){return e instanceof Error&&(0,u.trackError)("passport","sessionActivityError",e),t}})(e).then(()=>{eF[e.passportClient]=!1})},eK=async({params:e,ethSigner:t,rpcProvider:r,relayerClient:a,guardianClient:n,zkEvmAddress:i,flow:s})=>{let{relayerId:o}=await ew({transactionRequest:{to:i,value:0},ethSigner:t,rpcProvider:r,guardianClient:n,relayerClient:a,zkEvmAddress:i,flow:s});return n.withConfirmationScreen()(async()=>{let c=await eC({params:e,ethSigner:t,zkEvmAddress:i,rpcProvider:r,guardianClient:n,relayerClient:a,flow:s});return await ex(a,o,s),c})},eG=async({params:e,ethSigner:t,zkEvmAddress:r,flow:a})=>{if(!e||1!==e.length)throw new D(-32602,"im_signEjectionTransaction requires a singular param (hash)");let n=e[0];return await eA({transactionRequest:n,ethSigner:t,zkEvmAddress:r,flow:a})},eW=e=>"zkEvm"in e,eJ=class{#e;#tH;#tq;#J;#tz;#r;#a;#tK;#tG;#t;isPassport=!0;constructor({auth:e,config:t,multiRollupApiClients:r,passportEventEmitter:a,guardianClient:n,ethSigner:i,user:s,sessionActivityApiUrl:o}){this.#e=e,this.#tH=t,this.#r=n,this.#tz=a,this.#tq=o,this.#t=i,this.#a=new h.JsonRpcProvider(this.#tH.zkEvmRpcUrl,void 0,{staticNetwork:!0}),this.#tG=new U({config:this.#tH,rpcProvider:this.#a,auth:this.#e}),this.#tK=r,this.#J=new d.TypedEventEmitter,s&&eW(s)&&this.#tW(s.zkEvm.ethAddress),a.on(d.AuthEvents.LOGGED_IN,e=>{eW(e)&&this.#tW(e.zkEvm.ethAddress)}),a.on(d.AuthEvents.LOGGED_OUT,this.#tJ),a.on("accountsRequested",ez)}#tJ=()=>{this.#J.emit("accountsChanged",[])};async #tW(e,t){if(!this.#tq)return;let r=BigInt(1),a=async(t,a)=>await eE({params:t,ethSigner:this.#t,guardianClient:this.#r,rpcProvider:this.#a,relayerClient:this.#tG,zkEvmAddress:e,flow:a,nonceSpace:r,isBackgroundTransaction:!0});this.#tz.emit("accountsRequested",{sessionActivityApiUrl:this.#tq,sendTransaction:a,walletAddress:e,passportClient:t||await this.#e.getClientId()})}async #t$(){try{let e=await this.#e.getUser();return e&&eW(e)?e.zkEvm.ethAddress:void 0}catch{return}}async #tZ(e){switch(e.method){case"eth_requestAccounts":{let e=await this.#t$();if(e)return[e];let t=(0,u.trackFlow)("passport","ethRequestAccounts");try{let e,r=await this.#e.getUserOrLogin();return t.addEvent("endGetUserOrLogin"),eW(r)?e=r.zkEvm.ethAddress:(t.addEvent("startUserRegistration"),e=await V({ethSigner:this.#t,auth:this.#e,multiRollupApiClients:this.#tK,accessToken:r.accessToken,rpcProvider:this.#a,flow:t}),t.addEvent("endUserRegistration")),this.#J.emit("accountsChanged",[e]),(0,u.identify)({passportId:r.profile.sub}),this.#tW(e),[e]}catch(e){throw e instanceof Error?(0,u.trackError)("passport","ethRequestAccounts",e,{flowId:t.details.flowId}):t.addEvent("errored"),e}finally{t.addEvent("End")}}case"eth_sendTransaction":{let t=await this.#t$();if(!t)throw new D(4100,"Unauthorised - call eth_requestAccounts first");let r=(0,u.trackFlow)("passport","ethSendTransaction");try{return await this.#r.withConfirmationScreen({width:480,height:720})(async()=>await eE({params:e.params||[],ethSigner:this.#t,guardianClient:this.#r,rpcProvider:this.#a,relayerClient:this.#tG,zkEvmAddress:t,flow:r}))}catch(e){throw e instanceof Error?(0,u.trackError)("passport","eth_sendTransaction",e,{flowId:r.details.flowId}):r.addEvent("errored"),e}finally{r.addEvent("End")}}case"eth_accounts":{let e=await this.#t$();return e?[e]:[]}case"personal_sign":{let t=await this.#t$();if(!t)throw new D(4100,"Unauthorised - call eth_requestAccounts first");let r=(0,u.trackFlow)("passport","personalSign");try{return await this.#r.withConfirmationScreen({width:480,height:720})(async()=>this.#tH.forceScwDeployBeforeMessageSignature&&!(await C(this.#a,t)>BigInt(0))?await eK({params:e.params||[],zkEvmAddress:t,ethSigner:this.#t,rpcProvider:this.#a,guardianClient:this.#r,relayerClient:this.#tG,flow:r}):await eC({params:e.params||[],zkEvmAddress:t,ethSigner:this.#t,rpcProvider:this.#a,guardianClient:this.#r,relayerClient:this.#tG,flow:r}))}catch(e){throw e instanceof Error?(0,u.trackError)("passport","personal_sign",e,{flowId:r.details.flowId}):r.addEvent("errored"),e}finally{r.addEvent("End")}}case"eth_signTypedData":case"eth_signTypedData_v4":{if(!await this.#t$())throw new D(4100,"Unauthorised - call eth_requestAccounts first");let t=(0,u.trackFlow)("passport","ethSignTypedDataV4");try{return await this.#r.withConfirmationScreen({width:480,height:720})(async()=>await ek({method:e.method,params:e.params||[],ethSigner:this.#t,rpcProvider:this.#a,relayerClient:this.#tG,guardianClient:this.#r,flow:t}))}catch(e){throw e instanceof Error?(0,u.trackError)("passport","eth_signTypedData",e,{flowId:t.details.flowId}):t.addEvent("errored"),e}finally{t.addEvent("End")}}case"eth_chainId":{let{chainId:e}=await this.#a.getNetwork();return(0,h.toBeHex)(e)}case"eth_getBalance":case"eth_getCode":case"eth_getTransactionCount":{let[t,r]=e.params||[];return this.#a.send(e.method,[t,r||"latest"])}case"eth_getStorageAt":{let[t,r,a]=e.params||[];return this.#a.send(e.method,[t,r,a||"latest"])}case"eth_call":case"eth_estimateGas":{let[t,r]=e.params||[];return this.#a.send(e.method,[t,r||"latest"])}case"eth_gasPrice":case"eth_blockNumber":case"eth_getBlockByHash":case"eth_getBlockByNumber":case"eth_getTransactionByHash":case"eth_getTransactionReceipt":return this.#a.send(e.method,e.params||[]);case"im_signEjectionTransaction":{let t=await this.#t$();if(!t)throw new D(4100,"Unauthorised - call eth_requestAccounts first");let r=(0,u.trackFlow)("passport","imSignEjectionTransaction");try{return await eG({params:e.params||[],ethSigner:this.#t,zkEvmAddress:t,flow:r})}catch(e){throw e instanceof Error?(0,u.trackError)("passport","imSignEjectionTransaction",e,{flowId:r.details.flowId}):r.addEvent("errored"),e}finally{r.addEvent("End")}}case"im_addSessionActivity":{let[t]=e.params||[],r=await this.#t$();return r&&this.#tW(r,t),null}default:throw new D(4200,"Method not supported")}}async request(e){try{return this.#tZ(e)}catch(e){throw e instanceof D?e:e instanceof Error?new D(-32603,e.message):new D(-32603,"Internal error")}}on(e,t){this.#J.on(e,t)}removeListener(e,t){this.#J.removeListener(e,t)}},e$=class{passportDomain;zkEvmRpcUrl;relayerUrl;indexerMrBasePath;jsonRpcReferrer;forceScwDeployBeforeMessageSignature;crossSdkBridgeEnabled;feeTokenSymbol;constructor(e){this.passportDomain=e.passportDomain,this.zkEvmRpcUrl=e.zkEvmRpcUrl,this.relayerUrl=e.relayerUrl,this.indexerMrBasePath=e.indexerMrBasePath,this.jsonRpcReferrer=e.jsonRpcReferrer,this.forceScwDeployBeforeMessageSignature=e.forceScwDeployBeforeMessageSignature||!1,this.crossSdkBridgeEnabled=e.crossSdkBridgeEnabled||!1,this.feeTokenSymbol=e.feeTokenSymbol||"IMX"}},eZ=async(e,t,r=!0,a=!0)=>{let n=(0,u.trackFlow)("passport",t,r);try{return await e(n)}catch(e){throw e instanceof Error?(0,u.trackError)("passport",t,e,{flowId:n.details.flowId}):n.addEvent("errored"),e}finally{a&&n.addEvent("End")}},eQ=e=>e.reduce((e,t)=>`${e}${t.toString(16).padStart(2,"0")}`,""),eX=e=>{if("u">typeof TextEncoder)return new TextEncoder().encode(e);let t=unescape(encodeURIComponent(e)),r=new Uint8Array(t.length);for(let e=0;e{let t=eX(e),r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",a="";for(let e=0;e>18&63,f=o>>12&63,d=o>>6&63,l=63&o;a+=r[c]+r[f],a+=Number.isFinite(i)?r[d]:"=",a+=Number.isFinite(s)?r[l]:"="}return a},e0=class e extends h.AbstractSigner{auth;magicTeeApiClient;userWallet=null;createWalletPromise=null;constructor(e,t){super(),this.auth=e,this.magicTeeApiClient=t}async getUserWallet(){let{userWallet:e}=this;e||(e=await this.createWallet());let t=await this.getUserOrThrow();if(t.profile.sub!==e.userIdentifier&&(e=await this.createWallet(t)),(0,d.isUserZkEvm)(t)&&t.zkEvm.userAdminAddress.toLowerCase()!==e.walletAddress.toLowerCase())throw new ef(`Wallet address mismatch.Rollup: zkEVM, TEE address: ${e.walletAddress}, profile address: ${t.zkEvm.userAdminAddress}`,"WALLET_CONNECTION_ERROR");return e}async createWallet(t){return this.createWalletPromise||(this.createWalletPromise=new Promise(async(r,a)=>{try{this.userWallet=null;let n=t||await this.getUserOrThrow(),i=e.getHeaders(n);await eZ(async e=>{try{let t=performance.now(),a=await this.magicTeeApiClient.walletApi.createWalletV1WalletPost({xMagicChain:"ETH"},{headers:i});return(0,u.trackDuration)("passport",e.details.flowName,Math.round(performance.now()-t)),this.userWallet={userIdentifier:n.profile.sub,walletAddress:a.data.public_address},r(this.userWallet)}catch(t){let e="MagicTEE: Failed to initialise EOA";return ed(t)&&t.response?e+=` with status ${t.response.status}: ${JSON.stringify(t.response.data)}`:e+=`: ${t.message}`,a(Error(e))}},"magicCreateWallet")}catch(e){a(e)}finally{this.createWalletPromise=null}})),this.createWalletPromise}async getUserOrThrow(){let e=await this.auth.getUser();if(!e)throw new ef("User has been logged out","NOT_LOGGED_IN_ERROR");return e}static getHeaders(e){if(!e)throw new ef("User has been logged out","NOT_LOGGED_IN_ERROR");return{Authorization:`Bearer ${e.idToken}`}}async getAddress(){return(await this.getUserWallet()).walletAddress}async signMessage(t){await this.getUserWallet();let r=t instanceof Uint8Array?`0x${eQ(t)}`:t,a=await this.getUserOrThrow(),n=await e.getHeaders(a);return eZ(async e=>{try{let t=performance.now(),a=await this.magicTeeApiClient.signOperationsApi.signMessageV1WalletSignMessagePost({signMessageRequest:{message_base64:eY(r)},xMagicChain:"ETH"},{headers:n});return(0,u.trackDuration)("passport",e.details.flowName,Math.round(performance.now()-t)),a.data.signature}catch(t){let e="MagicTEE: Failed to sign message using EOA";throw ed(t)&&t.response?e+=` with status ${t.response.status}: ${JSON.stringify(t.response.data)}`:e+=`: ${t.message}`,Error(e)}},"magicSignMessage")}connect(){throw Error("Method not implemented.")}signTransaction(){throw Error("Method not implemented.")}signTypedData(){throw Error("Method not implemented.")}},e1={icon:'data:image/svg+xml,',name:"Immutable Passport",rdns:"com.immutable.passport",uuid:"3f0259bb-54c0-4ff0-85f2-6bb7c2d8b6c8"};function e2(e){if(typeof window>"u")return;let t=new CustomEvent("eip6963:announceProvider",{detail:Object.freeze(e)});window.dispatchEvent(t),window.addEventListener("eip6963:requestProvider",()=>window.dispatchEvent(t))}var e6=13371,e5=13473,e3={13371:{magicPublishableApiKey:"pk_live_10F423798A540ED7",magicProviderId:"aa80b860-8869-4f13-9000-6a6ad3d20017"},13473:{magicPublishableApiKey:"pk_live_10F423798A540ED7",magicProviderId:"aa80b860-8869-4f13-9000-6a6ad3d20017"}},e8={chainId:13371,name:"Immutable zkEVM",rpcUrl:"https://rpc.immutable.com",relayerUrl:"https://api.immutable.com/relayer-mr",apiUrl:"https://api.immutable.com",passportDomain:"https://passport.immutable.com",magicPublishableApiKey:e3[13371].magicPublishableApiKey,magicProviderId:e3[13371].magicProviderId,magicTeeBasePath:"https://tee.express.magiclabs.com"},e4={chainId:13473,name:"Immutable zkEVM Testnet",rpcUrl:"https://rpc.testnet.immutable.com",relayerUrl:"https://api.sandbox.immutable.com/relayer-mr",apiUrl:"https://api.sandbox.immutable.com",passportDomain:"https://passport.sandbox.immutable.com",magicPublishableApiKey:e3[13473].magicPublishableApiKey,magicProviderId:e3[13473].magicProviderId,magicTeeBasePath:"https://tee.express.magiclabs.com"},e9=[e4,e8],e7={chains:[e8]},te={chains:[e4]},tt={chains:e9},tr=/(sandbox|testnet)/i;async function ta(e={}){let t,r,a=e.chains&&e.chains.length>0?e.chains:e9,n=e.initialChainId||a[0].chainId,i=a.find(e=>e.chainId===n);if(!i)throw Error(`Initial chain ${n} not found in chains configuration`);let s=(0,l.createConfig)({basePath:i.apiUrl}),o=new l.MultiRollupApiClients({indexer:s,orderBook:s,passport:s}),c=e.auth??(t=function(e){if(e.passportDomain)return e.passportDomain;if(e.apiUrl)try{let t=new URL(e.apiUrl),r=t.hostname.replace("api.","passport.");return`${t.protocol}//${r}`}catch{return e.apiUrl.replace("api.","passport.")}return"https://passport.immutable.com"}(i),r="https://auth.immutable.com/im-logged-in",new d.Auth({clientId:!function(e){if(13473===e.chainId)return!0;let t=e.apiUrl||e.passportDomain||"";return tr.test(t)}(i)?"PtQRK4iRJ8GkXjiz6xfImMAYhPhW0cYk":"mjtCL8mt06BtbxSkp2vbrYStKWnXVZfo",redirectUri:r,popupRedirectUri:r,logoutRedirectUri:r,scope:"openid profile email offline_access transact",audience:"platform_api",authenticationDomain:"https://auth.immutable.com",passportDomain:t,popupOverlayOptions:e.popupOverlayOptions,crossSdkBridgeEnabled:e.crossSdkBridgeEnabled}));!e.auth&&"u">typeof window&&window.addEventListener("message",async e=>{if(e.data.code&&e.data.state){let t=new URLSearchParams(window.location.search);t.set("code",e.data.code),t.set("state",e.data.state),window.history.replaceState(null,"",`?${t.toString()}`),await c.loginCallback(),t.delete("code"),t.delete("state"),window.history.replaceState(null,"",`?${t.toString()}`)}});let f=c.getConfig(),u=await c.getUser(),h=new e$({passportDomain:i.passportDomain||i.apiUrl.replace("api.","passport."),zkEvmRpcUrl:i.rpcUrl,relayerUrl:i.relayerUrl,indexerMrBasePath:i.apiUrl,jsonRpcReferrer:e.jsonRpcReferrer,forceScwDeployBeforeMessageSignature:e.forceScwDeployBeforeMessageSignature,crossSdkBridgeEnabled:e.crossSdkBridgeEnabled,feeTokenSymbol:e.feeTokenSymbol}),p=new ep({config:h,auth:c,guardianApi:new l.mr.GuardianApi(s),authConfig:f}),b=function(e){if(e.magicPublishableApiKey&&e.magicProviderId)return{magicPublishableApiKey:e.magicPublishableApiKey,magicProviderId:e.magicProviderId};let{chainId:t}=e;if(t in e3)return e3[t];throw Error(`No Magic configuration available for chain ${e.chainId}. Please provide magicPublishableApiKey and magicProviderId in ChainConfig.`)}(i),g=i.magicTeeBasePath||"https://tee.express.magiclabs.com",m=new e0(c,new l.MagicTeeApiClients({basePath:g,timeout:1e4,magicPublishableApiKey:b.magicPublishableApiKey,magicProviderId:b.magicProviderId})),y=null;13371===i.chainId?y="https://api.immutable.com":13473===i.chainId?y="https://api.sandbox.immutable.com":i.apiUrl&&(y=i.apiUrl);let x=new eJ({auth:c,config:h,multiRollupApiClients:o,passportEventEmitter:e.passportEventEmitter||new d.TypedEventEmitter,guardianClient:p,ethSigner:m,user:u,sessionActivityApiUrl:y});return!1!==e.announceProvider&&e2({info:e1,provider:x}),x}async function tn(e,t){let r=await e.getUser();if(!r?.profile.sub)return[];let a={Authorization:`Bearer ${r.accessToken}`},{data:n}=await t.passportProfileApi.getUserInfo({headers:a});return n.linked_addresses}async function ti(e,t,r){let a=(0,u.trackFlow)("wallet","linkExternalWallet");try{let a=await e.getUser();if(!a)throw new ef("User is not logged in","NOT_LOGGED_IN_ERROR");if(!(0,d.isUserZkEvm)(a))throw new ef("User has not been registered on Immutable zkEVM","WALLET_CONNECTION_ERROR");let n={Authorization:`Bearer ${a.accessToken}`},i={type:r.type,wallet_address:r.walletAddress,signature:r.signature,nonce:r.nonce};return{...(await t.passportProfileApi.linkWalletV2({linkWalletV2Request:i},{headers:n})).data}}catch(t){if(t instanceof Error?(0,u.trackError)("wallet","linkExternalWallet",t):a.addEvent("errored"),ed(t)&&t.response){var n;if(t.response.data&&"object"==typeof(n=t.response.data)&&null!==n&&"code"in n&&"message"in n){let{code:e,message:r}=t.response.data;throw new ef(r,"WALLET_CONNECTION_ERROR")}if(t.response.status)throw new ef(`Link wallet request failed with status code ${t.response.status}`,"WALLET_CONNECTION_ERROR")}let e="Link wallet request failed";throw t instanceof Error&&(e+=`: ${t.message}`),new ef(e,"WALLET_CONNECTION_ERROR")}finally{a.addEvent("End")}}},{"@imtbl/auth":"bwDzx","@imtbl/generated-clients":"8BZnj","@imtbl/metrics":"7Q1ml",ethers:"jZqA6","@imtbl/toolkit":"7cpoh","@parcel/transformer-js/src/esmodule-helpers.js":"6aMVc"}],"7cpoh":[function(e,t,r){var a=e("@parcel/transformer-js/src/esmodule-helpers.js");a.defineInteropFlag(r),a.export(r,"convertToSignableToken",()=>d),a.export(r,"generateIMXAuthorisationHeaders",()=>c),a.export(r,"signMessage",()=>f),a.export(r,"signRaw",()=>o);var n=e("bn.js"),i=a.interopDefault(n),s=e("enc-utils");async function o(e,t){var r;return r=function(e,t=64){var r;let a,n=s.removeHexPrefix(e);return{r:new i.default(n.substring(0,t),"hex"),s:new i.default(n.substring(t,2*t),"hex"),recoveryParam:(r=n.substring(2*t,2*t+2),a=-1!==new(0,i.default)(r,16).cmp(new i.default(27))?new(0,i.default)(r,16).sub(new i.default(27)).toNumber():new(0,i.default)(r,16).toNumber(),r.trim()?a:void 0)}}(await t.signMessage(e)),s.addHexPrefix(s.padLeft(r.r.toString(16),64)+s.padLeft(r.s.toString(16),64)+s.padLeft(r.recoveryParam?.toString(16)||"",2))}async function c(e){let t=Math.floor(Date.now()/1e3).toString(),r=await o(t,e);return{timestamp:t,signature:r}}async function f(e,t){let r=await t.getAddress(),a=await o(e,t);return{message:e,ethAddress:r,ethSignature:a}}function d(e){switch(e.type){case"ERC721":return{type:"ERC721",data:{token_id:e.tokenId,token_address:e.tokenAddress}};case"ERC20":return{type:"ERC20",data:{token_address:e.tokenAddress}};default:return{type:"ETH",data:{decimals:18}}}}},{"bn.js":"6pNUR","enc-utils":"6ILTN","@parcel/transformer-js/src/esmodule-helpers.js":"6aMVc"}]},["8Vdv4"],"8Vdv4","parcelRequire59a4");

Bridge Running

\ No newline at end of file From 641d7003cd311788156e72f65ccaeca90cbbe07d Mon Sep 17 00:00:00 2001 From: Rodrigo Fournier Date: Wed, 17 Dec 2025 14:55:43 +1100 Subject: [PATCH 2/6] feat(passport): add support for 'subscribed' marketing consent status - Add Subscribed enum value to MarketingConsentStatus - Add parsing for 'subscribed' status in PassportUI login flow - Update ToApiString() method to handle 'subscribed' conversion Ensures compatibility with Auth0 default marketing consent value --- .../Runtime/Scripts/Private/Model/MarketingConsentStatus.cs | 2 ++ src/Packages/Passport/Runtime/Scripts/Public/PassportUI.cs | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/Packages/Passport/Runtime/Scripts/Private/Model/MarketingConsentStatus.cs b/src/Packages/Passport/Runtime/Scripts/Private/Model/MarketingConsentStatus.cs index 07e74fce..08ba1f55 100644 --- a/src/Packages/Passport/Runtime/Scripts/Private/Model/MarketingConsentStatus.cs +++ b/src/Packages/Passport/Runtime/Scripts/Private/Model/MarketingConsentStatus.cs @@ -9,6 +9,7 @@ namespace Immutable.Passport.Model public enum MarketingConsentStatus { OptedIn, + Subscribed, Unsubscribed } @@ -27,6 +28,7 @@ public static string ToApiString(this MarketingConsentStatus status) return status switch { MarketingConsentStatus.OptedIn => "opted_in", + MarketingConsentStatus.Subscribed => "subscribed", MarketingConsentStatus.Unsubscribed => "unsubscribed", _ => throw new ArgumentOutOfRangeException(nameof(status), status, "Unknown MarketingConsentStatus value") }; diff --git a/src/Packages/Passport/Runtime/Scripts/Public/PassportUI.cs b/src/Packages/Passport/Runtime/Scripts/Public/PassportUI.cs index e6086a99..f985fe67 100644 --- a/src/Packages/Passport/Runtime/Scripts/Public/PassportUI.cs +++ b/src/Packages/Passport/Runtime/Scripts/Public/PassportUI.cs @@ -547,6 +547,9 @@ private async void HandleLoginData(string jsonData) case "opted_in": loginOptions.marketingConsentStatus = MarketingConsentStatus.OptedIn; break; + case "subscribed": + loginOptions.marketingConsentStatus = MarketingConsentStatus.Subscribed; + break; case "unsubscribed": loginOptions.marketingConsentStatus = MarketingConsentStatus.Unsubscribed; break; From 4598abf348bf871c1fcbd7f4fbc695d542fd1507 Mon Sep 17 00:00:00 2001 From: Rodrigo Fournier Date: Wed, 17 Dec 2025 12:22:33 +1100 Subject: [PATCH 3/6] fix(passport): add user-friendly message for 409 error in registerOffchain Following the ts-immutable-sdk Passport v3 refactoring (commit 240cd2f15, Dec 8 2025), which introduced stricter validation via toUserImx() during user registration, we now explicitly handle the 409 Conflict error in ImxRegisterScript. When a user is already registered off-chain, the API returns a 409 error with USER_REGISTRATION_ERROR type. This change detects this specific scenario and displays a user-friendly message: 'Passport account already registered'. This ensures the UI tests (test_4_imx_functions) continue to pass and provides a better user experience when attempting to register an already registered account. --- .../Passport/ImxRegister/ImxRegisterScript.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/ImxRegister/ImxRegisterScript.cs b/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/ImxRegister/ImxRegisterScript.cs index c634a43d..671c48bd 100644 --- a/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/ImxRegister/ImxRegisterScript.cs +++ b/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/ImxRegister/ImxRegisterScript.cs @@ -43,7 +43,16 @@ public async void RegisterOffchain() } catch (PassportException e) { - ShowOutput($"Unable to register off-chain: {e.Message} ({e.Type})"); + // Handle 409 - account already registered + if (e.Type == PassportErrorType.USER_REGISTRATION_ERROR && + (e.Message.Contains("409") || e.Message.Contains("already registered"))) + { + ShowOutput("Passport account already registered"); + } + else + { + ShowOutput($"Unable to register off-chain: {e.Message} ({e.Type})"); + } } catch (Exception e) { @@ -58,4 +67,4 @@ private void ShowOutput(string message) Output.text = message; } } -} \ No newline at end of file +} From 2665adf5726d27d1a147890524f379f2735c5319 Mon Sep 17 00:00:00 2001 From: Rodrigo Fournier Date: Wed, 17 Dec 2025 13:31:35 +1100 Subject: [PATCH 4/6] fix(passport): apply 409 error handling to sample app ImxRegisterScript Apply the same 409 error handling fix to the sample app version of ImxRegisterScript.cs that was previously applied to the Samples~ package version. The CI tests use the sample app directory, so both files need the same fix. --- .../Passport/ImxRegister/ImxRegisterScript.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sample/Assets/Scripts/Passport/ImxRegister/ImxRegisterScript.cs b/sample/Assets/Scripts/Passport/ImxRegister/ImxRegisterScript.cs index c634a43d..671c48bd 100644 --- a/sample/Assets/Scripts/Passport/ImxRegister/ImxRegisterScript.cs +++ b/sample/Assets/Scripts/Passport/ImxRegister/ImxRegisterScript.cs @@ -43,7 +43,16 @@ public async void RegisterOffchain() } catch (PassportException e) { - ShowOutput($"Unable to register off-chain: {e.Message} ({e.Type})"); + // Handle 409 - account already registered + if (e.Type == PassportErrorType.USER_REGISTRATION_ERROR && + (e.Message.Contains("409") || e.Message.Contains("already registered"))) + { + ShowOutput("Passport account already registered"); + } + else + { + ShowOutput($"Unable to register off-chain: {e.Message} ({e.Type})"); + } } catch (Exception e) { @@ -58,4 +67,4 @@ private void ShowOutput(string message) Output.text = message; } } -} \ No newline at end of file +} From 9aef9f632ff377aac70f653f7607797c0bf54f6c Mon Sep 17 00:00:00 2001 From: Rodrigo Fournier Date: Thu, 18 Dec 2025 14:30:21 +1100 Subject: [PATCH 5/6] chore(passport): remove sdk modification and adapt test for the new 409 return --- .../Scripts/Passport/ImxRegister/ImxRegisterScript.cs | 11 +---------- sample/Tests/test/test.py | 11 +++++++---- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/sample/Assets/Scripts/Passport/ImxRegister/ImxRegisterScript.cs b/sample/Assets/Scripts/Passport/ImxRegister/ImxRegisterScript.cs index 671c48bd..09568c32 100644 --- a/sample/Assets/Scripts/Passport/ImxRegister/ImxRegisterScript.cs +++ b/sample/Assets/Scripts/Passport/ImxRegister/ImxRegisterScript.cs @@ -43,16 +43,7 @@ public async void RegisterOffchain() } catch (PassportException e) { - // Handle 409 - account already registered - if (e.Type == PassportErrorType.USER_REGISTRATION_ERROR && - (e.Message.Contains("409") || e.Message.Contains("already registered"))) - { - ShowOutput("Passport account already registered"); - } - else - { - ShowOutput($"Unable to register off-chain: {e.Message} ({e.Type})"); - } + ShowOutput($"Unable to register off-chain: {e.Message} ({e.Type})"); } catch (Exception e) { diff --git a/sample/Tests/test/test.py b/sample/Tests/test/test.py index a073cbdb..c770366a 100644 --- a/sample/Tests/test/test.py +++ b/sample/Tests/test/test.py @@ -114,14 +114,17 @@ def test_2_imx_functions(self): print(f"RegisterOffchainBtn output: {text}") self.assertEqual("Registering off-chain...", text) time.sleep(20) - if "Passport account already registered" in output.get_text(): + output_text = output.get_text() + # Accept either success message or 409 error (account already registered) + if "Successfully registered" in output_text or ("409" in output_text and "USER_REGISTRATION_ERROR" in output_text): break attempts += 1 - # Assert that the desired text is found after waiting + # Assert that registration completed (either success or 409 error for already registered) + output_text = output.get_text() self.assertTrue( - "Passport account already registered" in output.get_text(), - f"Expected 'Passport account already registered' not found. Actual output: '{output.get_text()}'" + "Successfully registered" in output_text or ("409" in output_text and "USER_REGISTRATION_ERROR" in output_text), + f"Expected 'Successfully registered' or '409 (USER_REGISTRATION_ERROR)' not found. Actual output: '{output_text}'" ) # Get address From f168b7f5808261dc21a3d23c4deca18013c3eb6c Mon Sep 17 00:00:00 2001 From: Rodrigo Fournier Date: Thu, 18 Dec 2025 14:38:02 +1100 Subject: [PATCH 6/6] revert(passport): remove custom 409 error handling from Samples~ ImxRegisterScript Revert the custom 409 error handling to show the original error message. This aligns with the test adaptation that was done in commit 9aef9f63 which updated test.py to accept the original error format. --- .../Scripts/Passport/ImxRegister/ImxRegisterScript.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/ImxRegister/ImxRegisterScript.cs b/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/ImxRegister/ImxRegisterScript.cs index 671c48bd..09568c32 100644 --- a/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/ImxRegister/ImxRegisterScript.cs +++ b/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/ImxRegister/ImxRegisterScript.cs @@ -43,16 +43,7 @@ public async void RegisterOffchain() } catch (PassportException e) { - // Handle 409 - account already registered - if (e.Type == PassportErrorType.USER_REGISTRATION_ERROR && - (e.Message.Contains("409") || e.Message.Contains("already registered"))) - { - ShowOutput("Passport account already registered"); - } - else - { - ShowOutput($"Unable to register off-chain: {e.Message} ({e.Type})"); - } + ShowOutput($"Unable to register off-chain: {e.Message} ({e.Type})"); } catch (Exception e) {