keyring-chatbot-agent-sdk-test 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -26,7 +26,7 @@ return e("div",{className:"message-content",children:a})},Oo={send_native:{label
26
26
  /* @__PURE__ */t("div",{className:"action-form-actions",children:[
27
27
  /* @__PURE__ */e("button",{className:"message-button",onClick:s,type:"button",disabled:c,children:u("formCancel")}),
28
28
  /* @__PURE__ */e("button",{className:"message-button",onClick:v,type:"button",disabled:c,children:u(c?"formProcessing":"formExecute")})]})]}):null},Po=({scrollContainerRef:n,threshold:t=200})=>{const[o,r]=a(!1);return i(()=>{const e=n.current;if(!e)return;const o=()=>{const{scrollTop:n,scrollHeight:o,clientHeight:a}=e;r(o-n-a>t)};return e.addEventListener("scroll",o,{passive:!0}),o(),()=>{e.removeEventListener("scroll",o)}},[n,t]),o?/* @__PURE__ */e("button",{className:"scroll-to-bottom-btn",onClick:()=>{n.current?.scrollTo({top:n.current.scrollHeight,behavior:"smooth"})},"aria-label":"Scroll to bottom",type:"button",children:/* @__PURE__ */e("svg",{width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",children:/* @__PURE__ */e("path",{d:"M9 3V15M9 15L4 10M9 15L14 10",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}):null},Ho={1:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",10:"0x4200000000000000000000000000000000000006",56:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",137:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",8453:"0x4200000000000000000000000000000000000006",42161:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"},Yo=[{name:"transfer",type:"function",stateMutability:"nonpayable",inputs:[{name:"to",type:"address"},{name:"amount",type:"uint256"}],outputs:[{name:"",type:"bool"}]},{name:"approve",type:"function",stateMutability:"nonpayable",inputs:[{name:"spender",type:"address"},{name:"amount",type:"uint256"}],outputs:[{name:"",type:"bool"}]},{name:"allowance",type:"function",stateMutability:"view",inputs:[{name:"owner",type:"address"},{name:"spender",type:"address"}],outputs:[{name:"",type:"uint256"}]}],Jo=[{name:"deposit",type:"function",stateMutability:"payable",inputs:[],outputs:[]},{name:"withdraw",type:"function",stateMutability:"nonpayable",inputs:[{name:"wad",type:"uint256"}],outputs:[]}],qo=[{name:"safeTransferFrom",type:"function",stateMutability:"nonpayable",inputs:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"tokenId",type:"uint256"}],outputs:[]}],Vo=[{name:"safeTransferFrom",type:"function",stateMutability:"nonpayable",inputs:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"id",type:"uint256"},{name:"amount",type:"uint256"},{name:"data",type:"bytes"}],outputs:[]}];function Wo(e,n){if(n)return n;const t=Ut[e];return t?.rpcUrls?.default?.http?.[0]}async function Go(e){const{transactionHash:n,chainId:t,pollingInterval:o=3e3,timeout:a=12e4,rpcUrl:i}=e,r=Wo(t,i);if(!r)throw new Error(`No RPC endpoint for chain ${t}`);const s=Date.now();for(;Date.now()-s<a;){try{const e=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionReceipt",params:[n]})}),t=await e.json();if(t.result){const e=t.result;return{status:"0x1"===e.status?"success":"fail",blockNumber:e.blockNumber,gasUsed:e.gasUsed,effectiveGasPrice:e.effectiveGasPrice}}}catch(c){}await new Promise(e=>setTimeout(e,o))}throw new Error(`Transaction ${n} was not mined within ${a/1e3}s`)}async function zo(e){const{tokenAddress:n,ownerAddress:t,spenderAddress:o,chainId:a,rpcUrl:i}=e,r=Wo(a,i);if(!r)return BigInt(0);try{const e=Dt({abi:Yo,functionName:"allowance",args:[t,o]}),a=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:e},"latest"]})}),i=await a.json();return i.result&&"0x"!==i.result?BigInt(i.result):BigInt(0)}catch(s){return BigInt(0)}}function Qo(e){const{tokenAddress:n,spenderAddress:t,fromAddress:o,chainId:a,tokenSymbol:i,amount:r}=e,s=r&&BigInt(r)>0n?BigInt(r):ie;return{from:o,to:n,data:Dt({abi:Yo,functionName:"approve",args:[t,s]}),value:"0",chainId:a,description:`Approve ${i||"token"} for swap`}}async function jo(e){const{address:n,chainId:t,rpcUrl:o}=e,a=Wo(t,o);if(!a)return new vo(0);try{const e=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getBalance",params:[n,"latest"]})}),t=await e.json();return t.result&&"0x"!==t.result?new vo(BigInt(t.result).toString()):new vo(0)}catch(i){return new vo(0)}}async function Xo(e){const{from:n,to:t,data:o,value:a,chainId:i,rpcUrl:r}=e,s=Wo(i,r);if(!s)return new vo(0);try{const[e,i]=await Promise.all([fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_estimateGas",params:[{from:n,to:t,data:o,...a&&"0"!==a?{value:a}:{}}]})}),fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:2,method:"eth_gasPrice",params:[]})})]),[r,c]=await Promise.all([e.json(),i.json()]),l=r.result?new vo(BigInt(r.result).toString()):new vo(0),d=c.result?new vo(BigInt(c.result).toString()):new vo(0);return l.times(d).times(1.1)}catch(c){return new vo(0)}}async function Ko(e){const{chainId:n,rpcUrl:t}=e,o=Wo(n,t);if(!o)return new vo(0);try{const e=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_gasPrice",params:[]})}),n=await e.json();return n.result&&"0x"!==n.result?new vo(BigInt(n.result).toString()):new vo(0)}catch(a){return new vo(0)}}var Zo,_o,$o={},ea={exports:{}},na=ea.exports;var ta=function(){if(_o)return $o;_o=1,Object.defineProperty($o,"m",{value:!0});var e,n,t,a=o,i=(e=a)&&"object"==typeof e&&"default"in e?e.default:e,r=(Zo||(Zo=1,n=ea,t=ea.exports,function(e,o){var a="function",i="undefined",r="object",s="string",c="major",l="model",d="name",u="type",f="vendor",m="version",h="architecture",p="console",w="mobile",b="tablet",g="smarttv",y="wearable",A="embedded",k="Amazon",v="Apple",C="ASUS",T="BlackBerry",E="Browser",I="Chrome",x="Firefox",S="Google",N="Honor",B="Huawei",R="LG",D="Microsoft",U="Motorola",F="Nvidia",O="OnePlus",L="Opera",M="OPPO",P="Samsung",H="Sharp",Y="Sony",J="Xiaomi",q="Zebra",V="Facebook",W="Chromium OS",G="Mac OS",z=" Browser",Q=function(e){for(var n={},t=0;t<e.length;t++)n[e[t].toUpperCase()]=e[t];return n},j=function(e,n){return typeof e===s&&-1!==X(n).indexOf(X(e))},X=function(e){return e.toLowerCase()},K=function(e,n){if(typeof e===s)return e=e.replace(/^\s\s*/,""),typeof n===i?e:e.substring(0,500)},Z=function(e,n){for(var t,i,s,c,l,d,u=0;u<n.length&&!l;){var f=n[u],m=n[u+1];for(t=i=0;t<f.length&&!l&&f[t];)if(l=f[t++].exec(e))for(s=0;s<m.length;s++)d=l[++i],typeof(c=m[s])===r&&c.length>0?2===c.length?typeof c[1]==a?this[c[0]]=c[1].call(this,d):this[c[0]]=c[1]:3===c.length?typeof c[1]!==a||c[1].exec&&c[1].test?this[c[0]]=d?d.replace(c[1],c[2]):o:this[c[0]]=d?c[1].call(this,d,c[2]):o:4===c.length&&(this[c[0]]=d?c[3].call(this,d.replace(c[1],c[2])):o):this[c]=d||o;u+=2}},_=function(e,n){for(var t in n)if(typeof n[t]===r&&n[t].length>0){for(var a=0;a<n[t].length;a++)if(j(n[t][a],e))return"?"===t?o:t}else if(j(n[t],e))return"?"===t?o:t;return n.hasOwnProperty("*")?n["*"]:e},$={ME:"4.90","NT 3.11":"NT3.51","NT 4.0":"NT4.0",2e3:"NT 5.0",XP:["NT 5.1","NT 5.2"],Vista:"NT 6.0",7:"NT 6.1",8:"NT 6.2",8.1:"NT 6.3",10:["NT 6.4","NT 10.0"],RT:"ARM"},ee={browser:[[/\b(?:crmo|crios)\/([\w\.]+)/i],[m,[d,"Chrome"]],[/edg(?:e|ios|a)?\/([\w\.]+)/i],[m,[d,"Edge"]],[/(opera mini)\/([-\w\.]+)/i,/(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i,/(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i],[d,m],[/opios[\/ ]+([\w\.]+)/i],[m,[d,L+" Mini"]],[/\bop(?:rg)?x\/([\w\.]+)/i],[m,[d,L+" GX"]],[/\bopr\/([\w\.]+)/i],[m,[d,L]],[/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i],[m,[d,"Baidu"]],[/\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i],[m,[d,"Maxthon"]],[/(kindle)\/([\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,/(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i,/(?:ms|\()(ie) ([\w\.]+)/i,/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon)\/([-\w\.]+)/i,/(heytap|ovi|115)browser\/([\d\.]+)/i,/(weibo)__([\d\.]+)/i],[d,m],[/quark(?:pc)?\/([-\w\.]+)/i],[m,[d,"Quark"]],[/\bddg\/([\w\.]+)/i],[m,[d,"DuckDuckGo"]],[/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i],[m,[d,"UC"+E]],[/microm.+\bqbcore\/([\w\.]+)/i,/\bqbcore\/([\w\.]+).+microm/i,/micromessenger\/([\w\.]+)/i],[m,[d,"WeChat"]],[/konqueror\/([\w\.]+)/i],[m,[d,"Konqueror"]],[/trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i],[m,[d,"IE"]],[/ya(?:search)?browser\/([\w\.]+)/i],[m,[d,"Yandex"]],[/slbrowser\/([\w\.]+)/i],[m,[d,"Smart Lenovo "+E]],[/(avast|avg)\/([\w\.]+)/i],[[d,/(.+)/,"$1 Secure "+E],m],[/\bfocus\/([\w\.]+)/i],[m,[d,x+" Focus"]],[/\bopt\/([\w\.]+)/i],[m,[d,L+" Touch"]],[/coc_coc\w+\/([\w\.]+)/i],[m,[d,"Coc Coc"]],[/dolfin\/([\w\.]+)/i],[m,[d,"Dolphin"]],[/coast\/([\w\.]+)/i],[m,[d,L+" Coast"]],[/miuibrowser\/([\w\.]+)/i],[m,[d,"MIUI"+z]],[/fxios\/([\w\.-]+)/i],[m,[d,x]],[/\bqihoobrowser\/?([\w\.]*)/i],[m,[d,"360"]],[/\b(qq)\/([\w\.]+)/i],[[d,/(.+)/,"$1Browser"],m],[/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i],[[d,/(.+)/,"$1"+z],m],[/samsungbrowser\/([\w\.]+)/i],[m,[d,P+" Internet"]],[/metasr[\/ ]?([\d\.]+)/i],[m,[d,"Sogou Explorer"]],[/(sogou)mo\w+\/([\d\.]+)/i],[[d,"Sogou Mobile"],m],[/(electron)\/([\w\.]+) safari/i,/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i,/m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i],[d,m],[/(lbbrowser|rekonq)/i,/\[(linkedin)app\]/i],[d],[/ome\/([\w\.]+) \w* ?(iron) saf/i,/ome\/([\w\.]+).+qihu (360)[es]e/i],[m,d],[/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i],[[d,V],m],[/(Klarna)\/([\w\.]+)/i,/(kakao(?:talk|story))[\/ ]([\w\.]+)/i,/(naver)\(.*?(\d+\.[\w\.]+).*\)/i,/(daum)apps[\/ ]([\w\.]+)/i,/safari (line)\/([\w\.]+)/i,/\b(line)\/([\w\.]+)\/iab/i,/(alipay)client\/([\w\.]+)/i,/(twitter)(?:and| f.+e\/([\w\.]+))/i,/(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i],[d,m],[/\bgsa\/([\w\.]+) .*safari\//i],[m,[d,"GSA"]],[/musical_ly(?:.+app_?version\/|_)([\w\.]+)/i],[m,[d,"TikTok"]],[/headlesschrome(?:\/([\w\.]+)| )/i],[m,[d,I+" Headless"]],[/ wv\).+(chrome)\/([\w\.]+)/i],[[d,I+" WebView"],m],[/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i],[m,[d,"Android "+E]],[/(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i],[d,m],[/version\/([\w\.\,]+) .*mobile\/\w+ (safari)/i],[m,[d,"Mobile Safari"]],[/version\/([\w(\.|\,)]+) .*(mobile ?safari|safari)/i],[m,d],[/webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i],[d,[m,_,{"1.0":"/8",1.2:"/1",1.3:"/3","2.0":"/412","2.0.2":"/416","2.0.3":"/417","2.0.4":"/419","?":"/"}]],[/(webkit|khtml)\/([\w\.]+)/i],[d,m],[/(navigator|netscape\d?)\/([-\w\.]+)/i],[[d,"Netscape"],m],[/(wolvic|librewolf)\/([\w\.]+)/i],[d,m],[/mobile vr; rv:([\w\.]+)\).+firefox/i],[m,[d,x+" Reality"]],[/ekiohf.+(flow)\/([\w\.]+)/i,/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,/(firefox)\/([\w\.]+)/i,/(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i,/(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,/\b(links) \(([\w\.]+)/i],[d,[m,/_/g,"."]],[/(cobalt)\/([\w\.]+)/i],[d,[m,/master.|lts./,""]]],cpu:[[/\b((amd|x|x86[-_]?|wow|win)64)\b/i],[[h,"amd64"]],[/(ia32(?=;))/i,/\b((i[346]|x)86)(pc)?\b/i],[[h,"ia32"]],[/\b(aarch64|arm(v?[89]e?l?|_?64))\b/i],[[h,"arm64"]],[/\b(arm(v[67])?ht?n?[fl]p?)\b/i],[[h,"armhf"]],[/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i],[[h,"arm"]],[/((ppc|powerpc)(64)?)( mac|;|\))/i],[[h,/ower/,"",X]],[/ sun4\w[;\)]/i],[[h,"sparc"]],[/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i],[[h,X]]],device:[[/\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i],[l,[f,P],[u,b]],[/\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,/samsung[- ]((?!sm-[lr])[-\w]+)/i,/sec-(sgh\w+)/i],[l,[f,P],[u,w]],[/(?:\/|\()(ip(?:hone|od)[\w, ]*)(?:\/|;)/i],[l,[f,v],[u,w]],[/\((ipad);[-\w\),; ]+apple/i,/applecoremedia\/[\w\.]+ \((ipad)/i,/\b(ipad)\d\d?,\d\d?[;\]].+ios/i],[l,[f,v],[u,b]],[/(macintosh);/i],[l,[f,v]],[/\b(sh-?[altvz]?\d\d[a-ekm]?)/i],[l,[f,H],[u,w]],[/\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i],[l,[f,N],[u,b]],[/honor([-\w ]+)[;\)]/i],[l,[f,N],[u,w]],[/\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i],[l,[f,B],[u,b]],[/(?:huawei)([-\w ]+)[;\)]/i,/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i],[l,[f,B],[u,w]],[/oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i,/\b((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i],[[l,/_/g," "],[f,J],[u,b]],[/\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i,/\b; (\w+) build\/hm\1/i,/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i,/oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i,/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i,/ ([\w ]+) miui\/v?\d/i],[[l,/_/g," "],[f,J],[u,w]],[/; (\w+) bui.+ oppo/i,/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i],[l,[f,M],[u,w]],[/\b(opd2(\d{3}a?))(?: bui|\))/i],[l,[f,_,{OnePlus:["304","403","203"],"*":M}],[u,b]],[/vivo (\w+)(?: bui|\))/i,/\b(v[12]\d{3}\w?[at])(?: bui|;)/i],[l,[f,"Vivo"],[u,w]],[/\b(rmx[1-3]\d{3})(?: bui|;|\))/i],[l,[f,"Realme"],[u,w]],[/\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,/\bmot(?:orola)?[- ](\w*)/i,/((?:moto(?! 360)[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i],[l,[f,U],[u,w]],[/\b(mz60\d|xoom[2 ]{0,2}) build\//i],[l,[f,U],[u,b]],[/((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i],[l,[f,R],[u,b]],[/(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,/\blg[-e;\/ ]+((?!browser|netcast|android tv|watch)\w+)/i,/\blg-?([\d\w]+) bui/i],[l,[f,R],[u,w]],[/(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i,/lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i],[l,[f,"Lenovo"],[u,b]],[/(nokia) (t[12][01])/i],[f,l,[u,b]],[/(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i,/nokia[-_ ]?(([-\w\. ]*))/i],[[l,/_/g," "],[u,w],[f,"Nokia"]],[/(pixel (c|tablet))\b/i],[l,[f,S],[u,b]],[/droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i],[l,[f,S],[u,w]],[/droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i],[l,[f,Y],[u,w]],[/sony tablet [ps]/i,/\b(?:sony)?sgp\w+(?: bui|\))/i],[[l,"Xperia Tablet"],[f,Y],[u,b]],[/ (kb2005|in20[12]5|be20[12][59])\b/i,/(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i],[l,[f,O],[u,w]],[/(alexa)webm/i,/(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i,/(kf[a-z]+)( bui|\)).+silk\//i],[l,[f,k],[u,b]],[/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i],[[l,/(.+)/g,"Fire Phone $1"],[f,k],[u,w]],[/(playbook);[-\w\),; ]+(rim)/i],[l,f,[u,b]],[/\b((?:bb[a-f]|st[hv])100-\d)/i,/\(bb10; (\w+)/i],[l,[f,T],[u,w]],[/(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i],[l,[f,C],[u,b]],[/ (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i],[l,[f,C],[u,w]],[/(nexus 9)/i],[l,[f,"HTC"],[u,b]],[/(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i,/(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,/(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i],[f,[l,/_/g," "],[u,w]],[/droid [\w\.]+; ((?:8[14]9[16]|9(?:0(?:48|60|8[01])|1(?:3[27]|66)|2(?:6[69]|9[56])|466))[gqswx])\w*(\)| bui)/i],[l,[f,"TCL"],[u,b]],[/(itel) ((\w+))/i],[[f,X],l,[u,_,{tablet:["p10001l","w7001"],"*":"mobile"}]],[/droid.+; ([ab][1-7]-?[0178a]\d\d?)/i],[l,[f,"Acer"],[u,b]],[/droid.+; (m[1-5] note) bui/i,/\bmz-([-\w]{2,})/i],[l,[f,"Meizu"],[u,w]],[/; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i],[l,[f,"Ulefone"],[u,w]],[/; (energy ?\w+)(?: bui|\))/i,/; energizer ([\w ]+)(?: bui|\))/i],[l,[f,"Energizer"],[u,w]],[/; cat (b35);/i,/; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i],[l,[f,"Cat"],[u,w]],[/((?:new )?andromax[\w- ]+)(?: bui|\))/i],[l,[f,"Smartfren"],[u,w]],[/droid.+; (a(?:015|06[35]|142p?))/i],[l,[f,"Nothing"],[u,w]],[/; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i,/archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i],[l,[f,"Archos"],[u,b]],[/archos ([\w ]+)( b|\))/i,/; (ac[3-6]\d\w{2,8})( b|\))/i],[l,[f,"Archos"],[u,w]],[/(imo) (tab \w+)/i,/(infinix) (x1101b?)/i],[f,l,[u,b]],[/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i,/; (hmd|imo) ([\w ]+?)(?: bui|\))/i,/(hp) ([\w ]+\w)/i,/(microsoft); (lumia[\w ]+)/i,/(lenovo)[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i,/(oppo) ?([\w ]+) bui/i],[f,l,[u,w]],[/(kobo)\s(ereader|touch)/i,/(hp).+(touchpad(?!.+tablet)|tablet)/i,/(kindle)\/([\w\.]+)/i,/(nook)[\w ]+build\/(\w+)/i,/(dell) (strea[kpr\d ]*[\dko])/i,/(le[- ]+pan)[- ]+(\w{1,9}) bui/i,/(trinity)[- ]*(t\d{3}) bui/i,/(gigaset)[- ]+(q\w{1,9}) bui/i,/(vodafone) ([\w ]+)(?:\)| bui)/i],[f,l,[u,b]],[/(surface duo)/i],[l,[f,D],[u,b]],[/droid [\d\.]+; (fp\du?)(?: b|\))/i],[l,[f,"Fairphone"],[u,w]],[/(u304aa)/i],[l,[f,"AT&T"],[u,w]],[/\bsie-(\w*)/i],[l,[f,"Siemens"],[u,w]],[/\b(rct\w+) b/i],[l,[f,"RCA"],[u,b]],[/\b(venue[\d ]{2,7}) b/i],[l,[f,"Dell"],[u,b]],[/\b(q(?:mv|ta)\w+) b/i],[l,[f,"Verizon"],[u,b]],[/\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i],[l,[f,"Barnes & Noble"],[u,b]],[/\b(tm\d{3}\w+) b/i],[l,[f,"NuVision"],[u,b]],[/\b(k88) b/i],[l,[f,"ZTE"],[u,b]],[/\b(nx\d{3}j) b/i],[l,[f,"ZTE"],[u,w]],[/\b(gen\d{3}) b.+49h/i],[l,[f,"Swiss"],[u,w]],[/\b(zur\d{3}) b/i],[l,[f,"Swiss"],[u,b]],[/\b((zeki)?tb.*\b) b/i],[l,[f,"Zeki"],[u,b]],[/\b([yr]\d{2}) b/i,/\b(dragon[- ]+touch |dt)(\w{5}) b/i],[[f,"Dragon Touch"],l,[u,b]],[/\b(ns-?\w{0,9}) b/i],[l,[f,"Insignia"],[u,b]],[/\b((nxa|next)-?\w{0,9}) b/i],[l,[f,"NextBook"],[u,b]],[/\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i],[[f,"Voice"],l,[u,w]],[/\b(lvtel\-)?(v1[12]) b/i],[[f,"LvTel"],l,[u,w]],[/\b(ph-1) /i],[l,[f,"Essential"],[u,w]],[/\b(v(100md|700na|7011|917g).*\b) b/i],[l,[f,"Envizen"],[u,b]],[/\b(trio[-\w\. ]+) b/i],[l,[f,"MachSpeed"],[u,b]],[/\btu_(1491) b/i],[l,[f,"Rotor"],[u,b]],[/((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i],[l,[f,F],[u,b]],[/(sprint) (\w+)/i],[f,l,[u,w]],[/(kin\.[onetw]{3})/i],[[l,/\./g," "],[f,D],[u,w]],[/droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i],[l,[f,q],[u,b]],[/droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i],[l,[f,q],[u,w]],[/smart-tv.+(samsung)/i],[f,[u,g]],[/hbbtv.+maple;(\d+)/i],[[l,/^/,"SmartTV"],[f,P],[u,g]],[/(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i],[[f,R],[u,g]],[/(apple) ?tv/i],[f,[l,v+" TV"],[u,g]],[/crkey/i],[[l,I+"cast"],[f,S],[u,g]],[/droid.+aft(\w+)( bui|\))/i],[l,[f,k],[u,g]],[/(shield \w+ tv)/i],[l,[f,F],[u,g]],[/\(dtv[\);].+(aquos)/i,/(aquos-tv[\w ]+)\)/i],[l,[f,H],[u,g]],[/(bravia[\w ]+)( bui|\))/i],[l,[f,Y],[u,g]],[/(mi(tv|box)-?\w+) bui/i],[l,[f,J],[u,g]],[/Hbbtv.*(technisat) (.*);/i],[f,l,[u,g]],[/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i,/hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i],[[f,K],[l,K],[u,g]],[/droid.+; ([\w- ]+) (?:android tv|smart[- ]?tv)/i],[l,[u,g]],[/\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i],[[u,g]],[/(ouya)/i,/(nintendo) ([wids3utch]+)/i],[f,l,[u,p]],[/droid.+; (shield)( bui|\))/i],[l,[f,F],[u,p]],[/(playstation \w+)/i],[l,[f,Y],[u,p]],[/\b(xbox(?: one)?(?!; xbox))[\); ]/i],[l,[f,D],[u,p]],[/\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i],[l,[f,P],[u,y]],[/((pebble))app/i,/(asus|google|lg|oppo) ((pixel |zen)?watch[\w ]*)( bui|\))/i],[f,l,[u,y]],[/(ow(?:19|20)?we?[1-3]{1,3})/i],[l,[f,M],[u,y]],[/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i],[l,[f,v],[u,y]],[/(opwwe\d{3})/i],[l,[f,O],[u,y]],[/(moto 360)/i],[l,[f,U],[u,y]],[/(smartwatch 3)/i],[l,[f,Y],[u,y]],[/(g watch r)/i],[l,[f,R],[u,y]],[/droid.+; (wt63?0{2,3})\)/i],[l,[f,q],[u,y]],[/droid.+; (glass) \d/i],[l,[f,S],[u,y]],[/(pico) (4|neo3(?: link|pro)?)/i],[f,l,[u,y]],[/; (quest( \d| pro)?)/i],[l,[f,V],[u,y]],[/(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i],[f,[u,A]],[/(aeobc)\b/i],[l,[f,k],[u,A]],[/(homepod).+mac os/i],[l,[f,v],[u,A]],[/windows iot/i],[[u,A]],[/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+? mobile safari/i],[l,[u,w]],[/droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i],[l,[u,b]],[/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i],[[u,b]],[/(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i],[[u,w]],[/droid .+?; ([\w\. -]+)( bui|\))/i],[l,[f,"Generic"]]],engine:[[/windows.+ edge\/([\w\.]+)/i],[m,[d,"EdgeHTML"]],[/(arkweb)\/([\w\.]+)/i],[d,m],[/webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i],[m,[d,"Blink"]],[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i,/ekioh(flow)\/([\w\.]+)/i,/(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i,/(icab)[\/ ]([23]\.[\d\.]+)/i,/\b(libweb)/i],[d,m],[/ladybird\//i],[[d,"LibWeb"]],[/rv\:([\w\.]{1,9})\b.+(gecko)/i],[m,d]],os:[[/microsoft (windows) (vista|xp)/i],[d,m],[/(windows (?:phone(?: os)?|mobile|iot))[\/ ]?([\d\.\w ]*)/i],[d,[m,_,$]],[/windows nt 6\.2; (arm)/i,/windows[\/ ]([ntce\d\. ]+\w)(?!.+xbox)/i,/(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i],[[m,_,$],[d,"Windows"]],[/[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i,/(?:ios;fbsv\/|iphone.+ios[\/ ])([\d\.]+)/i,/cfnetwork\/.+darwin/i],[[m,/_/g,"."],[d,"iOS"]],[/(mac os x) ?([\w\. ]*)/i,/(macintosh|mac_powerpc\b)(?!.+haiku)/i],[[d,G],[m,/_/g,"."]],[/droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i],[m,d],[/(ubuntu) ([\w\.]+) like android/i],[[d,/(.+)/,"$1 Touch"],m],[/(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen|webos)\w*[-\/; ]?([\d\.]*)/i],[d,m],[/\(bb(10);/i],[m,[d,T]],[/(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i],[m,[d,"Symbian"]],[/mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i],[m,[d,x+" OS"]],[/web0s;.+rt(tv)/i,/\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i],[m,[d,"webOS"]],[/watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i],[m,[d,"watchOS"]],[/crkey\/([\d\.]+)/i],[m,[d,I+"cast"]],[/(cros) [\w]+(?:\)| ([\w\.]+)\b)/i],[[d,W],m],[/panasonic;(viera)/i,/(netrange)mmh/i,/(nettv)\/(\d+\.[\w\.]+)/i,/(nintendo|playstation) ([wids345portablevuch]+)/i,/(xbox); +xbox ([^\);]+)/i,/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,/(mint)[\/\(\) ]?(\w*)/i,/(mageia|vectorlinux)[; ]/i,/([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,/(hurd|linux)(?: arm\w*| x86\w*| ?)([\w\.]*)/i,/(gnu) ?([\w\.]*)/i,/\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i,/(haiku) (\w+)/i],[d,m],[/(sunos) ?([\w\.\d]*)/i],[[d,"Solaris"],m],[/((?:open)?solaris)[-\/ ]?([\w\.]*)/i,/(aix) ((\d)(?=\.|\)| )[\w\.])*/i,/\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux|serenityos)/i,/(unix) ?([\w\.]*)/i],[d,m]]},ne=function(n,t){if(typeof n===r&&(t=n,n=o),!(this instanceof ne))return new ne(n,t).getResult();var p=typeof e!==i&&e.navigator?e.navigator:o,g=n||(p&&p.userAgent?p.userAgent:""),y=p&&p.userAgentData?p.userAgentData:o,A=t?function(e,n){var t={};for(var o in e)n[o]&&n[o].length%2==0?t[o]=n[o].concat(e[o]):t[o]=e[o];return t}(ee,t):ee,k=p&&p.userAgent==g;return this.getBrowser=function(){var e,n={};return n[d]=o,n[m]=o,Z.call(n,g,A.browser),n[c]=typeof(e=n[m])===s?e.replace(/[^\d\.]/g,"").split(".")[0]:o,k&&p&&p.brave&&typeof p.brave.isBrave==a&&(n[d]="Brave"),n},this.getCPU=function(){var e={};return e[h]=o,Z.call(e,g,A.cpu),e},this.getDevice=function(){var e={};return e[f]=o,e[l]=o,e[u]=o,Z.call(e,g,A.device),k&&!e[u]&&y&&y.mobile&&(e[u]=w),k&&"Macintosh"==e[l]&&p&&typeof p.standalone!==i&&p.maxTouchPoints&&p.maxTouchPoints>2&&(e[l]="iPad",e[u]=b),e},this.getEngine=function(){var e={};return e[d]=o,e[m]=o,Z.call(e,g,A.engine),e},this.getOS=function(){var e={};return e[d]=o,e[m]=o,Z.call(e,g,A.os),k&&!e[d]&&y&&y.platform&&"Unknown"!=y.platform&&(e[d]=y.platform.replace(/chrome os/i,W).replace(/macos/i,G)),e},this.getResult=function(){return{ua:this.getUA(),browser:this.getBrowser(),engine:this.getEngine(),os:this.getOS(),device:this.getDevice(),cpu:this.getCPU()}},this.getUA=function(){return g},this.setUA=function(e){return g=typeof e===s&&e.length>500?K(e,500):e,this},this.setUA(g),this};ne.VERSION="1.0.41",ne.BROWSER=Q([d,m,c]),ne.CPU=Q([h]),ne.DEVICE=Q([l,f,u,p,w,g,b,y,A]),ne.ENGINE=ne.OS=Q([d,m]),n.exports&&(t=n.exports=ne),t.UAParser=ne;var te=typeof e!==i&&(e.jQuery||e.Zepto);if(te&&!te.ua){var oe=new ne;te.ua=oe.getResult(),te.ua.get=function(){return oe.getUA()},te.ua.set=function(e){oe.setUA(e);var n=oe.getResult();for(var t in n)te.ua[t]=n[t]}}}("object"==typeof window?window:na)),ea.exports),s=new r,c=s.getBrowser(),l=s.getCPU(),d=s.getDevice(),u=s.getEngine(),f=s.getOS(),m=s.getUA(),h=function(e){return s.setUA(e)},p=function(e){if(e){var n=new r(e);return{UA:n,browser:n.getBrowser(),cpu:n.getCPU(),device:n.getDevice(),engine:n.getEngine(),os:n.getOS(),ua:n.getUA(),setUserAgent:function(e){return n.setUA(e)}}}},w=/* @__PURE__ */Object.freeze({ClientUAInstance:s,browser:c,cpu:l,device:d,engine:u,os:f,ua:m,setUa:h,parseUserAgent:p});function b(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter(function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable})),t.push.apply(t,o)}return t}function g(e){return(g="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function y(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function A(){return A=Object.assign||function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o])}return e},A.apply(this,arguments)}function k(e){return(k=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function v(e,n){return(v=Object.setPrototypeOf||function(e,n){return e.__proto__=n,e})(e,n)}function C(e,n){if(null==e)return{};var t,o,a=function(e,n){if(null==e)return{};var t,o,a={},i=Object.keys(e);for(o=0;o<i.length;o++)t=i[o],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o<i.length;o++)t=i[o],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}function T(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function E(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,o=new Array(n);t<n;t++)o[t]=e[t];return o}var I="mobile",x="tablet",S="smarttv",N="console",B="wearable",R="embedded",D=void 0,U={Chrome:"Chrome",Firefox:"Firefox",Opera:"Opera",Yandex:"Yandex",Safari:"Safari",InternetExplorer:"Internet Explorer",Edge:"Edge",Chromium:"Chromium",Ie:"IE",MobileSafari:"Mobile Safari",EdgeChromium:"Edge Chromium",MIUI:"MIUI Browser",SamsungBrowser:"Samsung Browser"},F={IOS:"iOS",Android:"Android",WindowsPhone:"Windows Phone",Windows:"Windows",MAC_OS:"Mac OS"},O={isMobile:!1,isTablet:!1,isBrowser:!1,isSmartTV:!1,isConsole:!1,isWearable:!1},L=function(e){return e||(arguments.length>1&&void 0!==arguments[1]?arguments[1]:"none")},M=function(){return!("undefined"==typeof window||!window.navigator&&!navigator)&&(window.navigator||navigator)},P=function(e){var n=M();return n&&n.platform&&(-1!==n.platform.indexOf(e)||"MacIntel"===n.platform&&n.maxTouchPoints>1&&!window.MSStream)},H=function(e){return e.type===I},Y=function(e){return e.type===x},J=function(e){var n=e.type;return n===I||n===x},q=function(e){return e.type===S},V=function(e){return e.type===D},W=function(e){return e.type===B},G=function(e){return e.type===N},z=function(e){return e.type===R},Q=function(e){var n=e.vendor;return L(n)},j=function(e){var n=e.model;return L(n)},X=function(e){var n=e.type;return L(n,"browser")},K=function(e){return e.name===F.Android},Z=function(e){return e.name===F.Windows},_=function(e){return e.name===F.MAC_OS},$=function(e){return e.name===F.WindowsPhone},ee=function(e){return e.name===F.IOS},ne=function(e){var n=e.version;return L(n)},te=function(e){var n=e.name;return L(n)},oe=function(e){return e.name===U.Chrome},ae=function(e){return e.name===U.Firefox},ie=function(e){return e.name===U.Chromium},re=function(e){return e.name===U.Edge},se=function(e){return e.name===U.Yandex},ce=function(e){var n=e.name;return n===U.Safari||n===U.MobileSafari},le=function(e){return e.name===U.MobileSafari},de=function(e){return e.name===U.Opera},ue=function(e){var n=e.name;return n===U.InternetExplorer||n===U.Ie},fe=function(e){return e.name===U.MIUI},me=function(e){return e.name===U.SamsungBrowser},he=function(e){var n=e.version;return L(n)},pe=function(e){var n=e.major;return L(n)},we=function(e){var n=e.name;return L(n)},be=function(e){var n=e.name;return L(n)},ge=function(e){var n=e.version;return L(n)},ye=function(){var e=M(),n=e&&e.userAgent&&e.userAgent.toLowerCase();return"string"==typeof n&&/electron/.test(n)},Ae=function(e){return"string"==typeof e&&-1!==e.indexOf("Edg/")},ke=function(){var e=M();return e&&(/iPad|iPhone|iPod/.test(e.platform)||"MacIntel"===e.platform&&e.maxTouchPoints>1)&&!window.MSStream},ve=function(){return P("iPad")},Ce=function(){return P("iPhone")},Te=function(){return P("iPod")},Ee=function(e){return L(e)};function Ie(e){var n=e||w,t=n.device,o=n.browser,a=n.os,i=n.engine,r=n.ua;return{isSmartTV:q(t),isConsole:G(t),isWearable:W(t),isEmbedded:z(t),isMobileSafari:le(o)||ve(),isChromium:ie(o),isMobile:J(t)||ve(),isMobileOnly:H(t),isTablet:Y(t)||ve(),isBrowser:V(t),isDesktop:V(t),isAndroid:K(a),isWinPhone:$(a),isIOS:ee(a)||ve(),isChrome:oe(o),isFirefox:ae(o),isSafari:ce(o),isOpera:de(o),isIE:ue(o),osVersion:ne(a),osName:te(a),fullBrowserVersion:he(o),browserVersion:pe(o),browserName:we(o),mobileVendor:Q(t),mobileModel:j(t),engineName:be(i),engineVersion:ge(i),getUA:Ee(r),isEdge:re(o)||Ae(r),isYandex:se(o),deviceType:X(t),isIOS13:ke(),isIPad13:ve(),isIPhone13:Ce(),isIPod13:Te(),isElectron:ye(),isEdgeChromium:Ae(r),isLegacyEdge:re(o)&&!Ae(r),isWindows:Z(a),isMacOs:_(a),isMIUI:fe(o),isSamsungBrowser:me(o)}}var xe=q(d),Se=G(d),Ne=W(d),Be=z(d),Re=le(c)||ve(),De=ie(c),Ue=J(d)||ve(),Fe=H(d),Oe=Y(d)||ve(),Le=V(d),Me=V(d),Pe=K(f),He=$(f),Ye=ee(f)||ve(),Je=oe(c),qe=ae(c),Ve=ce(c),We=de(c),Ge=ue(c),ze=ne(f),Qe=te(f),je=he(c),Xe=pe(c),Ke=we(c),Ze=Q(d),_e=j(d),$e=be(u),en=ge(u),nn=Ee(m),tn=re(c)||Ae(m),on=se(c),an=X(d),rn=ke(),sn=ve(),cn=Ce(),ln=Te(),dn=ye(),un=Ae(m),fn=re(c)&&!Ae(m),mn=Z(f),hn=_(f),pn=fe(c),wn=me(c);function bn(e){var n=e||window.navigator.userAgent;return p(n)}return $o.AndroidView=function(e){var n=e.renderWithFragment,t=e.children,o=C(e,["renderWithFragment","children"]);return Pe?n?i.createElement(a.Fragment,null,t):i.createElement("div",o,t):null},$o.BrowserTypes=U,$o.BrowserView=function(e){var n=e.renderWithFragment,t=e.children,o=C(e,["renderWithFragment","children"]);return Le?n?i.createElement(a.Fragment,null,t):i.createElement("div",o,t):null},$o.ConsoleView=function(e){var n=e.renderWithFragment,t=e.children,o=C(e,["renderWithFragment","children"]);return Se?n?i.createElement(a.Fragment,null,t):i.createElement("div",o,t):null},$o.CustomView=function(e){var n=e.renderWithFragment,t=e.children;e.viewClassName,e.style;var o=e.condition,r=C(e,["renderWithFragment","children","viewClassName","style","condition"]);return o?n?i.createElement(a.Fragment,null,t):i.createElement("div",r,t):null},$o.IEView=function(e){var n=e.renderWithFragment,t=e.children,o=C(e,["renderWithFragment","children"]);return Ge?n?i.createElement(a.Fragment,null,t):i.createElement("div",o,t):null},$o.IOSView=function(e){var n=e.renderWithFragment,t=e.children,o=C(e,["renderWithFragment","children"]);return Ye?n?i.createElement(a.Fragment,null,t):i.createElement("div",o,t):null},$o.MobileOnlyView=function(e){var n=e.renderWithFragment,t=e.children;e.viewClassName,e.style;var o=C(e,["renderWithFragment","children","viewClassName","style"]);return Fe?n?i.createElement(a.Fragment,null,t):i.createElement("div",o,t):null},$o.MobileView=function(e){var n=e.renderWithFragment,t=e.children,o=C(e,["renderWithFragment","children"]);return Ue?n?i.createElement(a.Fragment,null,t):i.createElement("div",o,t):null},$o.OsTypes=F,$o.SmartTVView=function(e){var n=e.renderWithFragment,t=e.children,o=C(e,["renderWithFragment","children"]);return xe?n?i.createElement(a.Fragment,null,t):i.createElement("div",o,t):null},$o.TabletView=function(e){var n=e.renderWithFragment,t=e.children,o=C(e,["renderWithFragment","children"]);return Oe?n?i.createElement(a.Fragment,null,t):i.createElement("div",o,t):null},$o.WearableView=function(e){var n=e.renderWithFragment,t=e.children,o=C(e,["renderWithFragment","children"]);return Ne?n?i.createElement(a.Fragment,null,t):i.createElement("div",o,t):null},$o.WinPhoneView=function(e){var n=e.renderWithFragment,t=e.children,o=C(e,["renderWithFragment","children"]);return He?n?i.createElement(a.Fragment,null,t):i.createElement("div",o,t):null},$o.browserName=Ke,$o.browserVersion=Xe,$o.deviceDetect=function(e){var n=e?p(e):w,t=n.device,o=n.browser,a=n.engine,i=n.os,r=n.ua,s=function(e){switch(e){case I:return{isMobile:!0};case x:return{isTablet:!0};case S:return{isSmartTV:!0};case N:return{isConsole:!0};case B:return{isWearable:!0};case D:return{isBrowser:!0};case R:return{isEmbedded:!0};default:return O}}(t.type),c=s.isBrowser,l=s.isMobile,d=s.isTablet,u=s.isSmartTV,f=s.isConsole,m=s.isWearable,h=s.isEmbedded;return c?function(e,n,t,o,a){return{isBrowser:e,browserMajorVersion:L(n.major),browserFullVersion:L(n.version),browserName:L(n.name),engineName:L(t.name),engineVersion:L(t.version),osName:L(o.name),osVersion:L(o.version),userAgent:L(a)}}(c,o,a,i,r):u?function(e,n,t,o){return{isSmartTV:e,engineName:L(n.name),engineVersion:L(n.version),osName:L(t.name),osVersion:L(t.version),userAgent:L(o)}}(u,a,i,r):f?function(e,n,t,o){return{isConsole:e,engineName:L(n.name),engineVersion:L(n.version),osName:L(t.name),osVersion:L(t.version),userAgent:L(o)}}(f,a,i,r):l||d?function(e,n,t,o){return function(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?b(Object(t),!0).forEach(function(n){y(e,n,t[n])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):b(Object(t)).forEach(function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))})}return e}({},e,{vendor:L(n.vendor),model:L(n.model),os:L(t.name),osVersion:L(t.version),ua:L(o)})}(s,t,i,r):m?function(e,n,t,o){return{isWearable:e,engineName:L(n.name),engineVersion:L(n.version),osName:L(t.name),osVersion:L(t.version),userAgent:L(o)}}(m,a,i,r):h?function(e,n,t,o,a){return{isEmbedded:e,vendor:L(n.vendor),model:L(n.model),engineName:L(t.name),engineVersion:L(t.version),osName:L(o.name),osVersion:L(o.version),userAgent:L(a)}}(h,t,a,i,r):void 0},$o.deviceType=an,$o.engineName=$e,$o.engineVersion=en,$o.fullBrowserVersion=je,$o.getSelectorsByUserAgent=function(e){if(e&&"string"==typeof e){var n=p(e);return Ie({device:n.device,browser:n.browser,os:n.os,engine:n.engine,ua:n.ua})}},$o.getUA=nn,$o.isAndroid=Pe,$o.isBrowser=Le,$o.isChrome=Je,$o.isChromium=De,$o.isConsole=Se,$o.isDesktop=Me,$o.isEdge=tn,$o.isEdgeChromium=un,$o.isElectron=dn,$o.isEmbedded=Be,$o.isFirefox=qe,$o.isIE=Ge,$o.isIOS=Ye,$o.isIOS13=rn,$o.isIPad13=sn,$o.isIPhone13=cn,$o.isIPod13=ln,$o.isLegacyEdge=fn,$o.isMIUI=pn,$o.isMacOs=hn,$o.isMobile=Ue,$o.isMobileOnly=Fe,$o.isMobileSafari=Re,$o.isOpera=We,$o.isSafari=Ve,$o.isSamsungBrowser=wn,$o.isSmartTV=xe,$o.isTablet=Oe,$o.isWearable=Ne,$o.isWinPhone=He,$o.isWindows=mn,$o.isYandex=on,$o.mobileModel=_e,$o.mobileVendor=Ze,$o.osName=Qe,$o.osVersion=ze,$o.parseUserAgent=p,$o.setUserAgent=function(e){return h(e)},$o.useDeviceData=bn,$o.useDeviceSelectors=function(e){var n=bn(e||window.navigator.userAgent);return[Ie(n),n]},$o.useMobileOrientation=function(){var e,n,t=(e=a.useState(function(){var e=window.innerWidth>window.innerHeight?90:0;return{isPortrait:0===e,isLandscape:90===e,orientation:0===e?"portrait":"landscape"}}),n=2,function(e){if(Array.isArray(e))return e}(e)||function(e,n){var t=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=t){var o,a,i=[],r=!0,s=!1;try{for(t=t.call(e);!(r=(o=t.next()).done)&&(i.push(o.value),!n||i.length!==n);r=!0);}catch(c){s=!0,a=c}finally{try{r||null==t.return||t.return()}finally{if(s)throw a}}return i}}(e,n)||function(e,n){if(e){if("string"==typeof e)return E(e,n);var t=Object.prototype.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?E(e,n):void 0}}(e,n)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),o=t[0],i=t[1],r=a.useCallback(function(){var e=window.innerWidth>window.innerHeight?90:0,n={isPortrait:0===e,isLandscape:90===e,orientation:0===e?"portrait":"landscape"};o.orientation!==n.orientation&&i(n)},[o.orientation]);return a.useEffect(function(){return void 0!==("undefined"==typeof window?"undefined":g(window))&&Ue&&(r(),window.addEventListener("load",r,!1),window.addEventListener("resize",r,!1)),function(){window.removeEventListener("resize",r,!1),window.removeEventListener("load",r,!1)}},[r]),o},$o.withOrientationChange=function(e){/* @__PURE__ */
29
- return function(n){function t(e){var n;return function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}(this,t),(n=function(e,n){if(n&&("object"==typeof n||"function"==typeof n))return n;if(void 0!==n)throw new TypeError("Derived constructors may only return object or undefined");return T(e)}(this,k(t).call(this,e))).isEventListenerAdded=!1,n.handleOrientationChange=n.handleOrientationChange.bind(T(n)),n.onOrientationChange=n.onOrientationChange.bind(T(n)),n.onPageLoad=n.onPageLoad.bind(T(n)),n.state={isLandscape:!1,isPortrait:!1},n}return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),n&&v(e,n)}(t,n),o=t,(a=[{key:"handleOrientationChange",value:function(){this.isEventListenerAdded||(this.isEventListenerAdded=!0);var e=window.innerWidth>window.innerHeight?90:0;this.setState({isPortrait:0===e,isLandscape:90===e})}},{key:"onOrientationChange",value:function(){this.handleOrientationChange()}},{key:"onPageLoad",value:function(){this.handleOrientationChange()}},{key:"componentDidMount",value:function(){void 0!==("undefined"==typeof window?"undefined":g(window))&&Ue&&(this.isEventListenerAdded?window.removeEventListener("load",this.onPageLoad,!1):(this.handleOrientationChange(),window.addEventListener("load",this.onPageLoad,!1)),window.addEventListener("resize",this.onOrientationChange,!1))}},{key:"componentWillUnmount",value:function(){window.removeEventListener("resize",this.onOrientationChange,!1)}},{key:"render",value:function(){return i.createElement(e,A({},this.props,{isLandscape:this.state.isLandscape,isPortrait:this.state.isPortrait}))}}])&&function(e,n){for(var t=0;t<n.length;t++){var o=n[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}(o.prototype,a),t;var o,a}(i.Component)},$o}();const oa=new class extends Co{enableGoogleSearch=!0;constructor(){super("https://nft-demo.keyring.app")}async generateContent(e,n){try{const t=`\nBelow is the system context and conversation history. Use it for context but prioritize the instructions at the end.\n\n---\nSYSTEM CONTEXT & HISTORY:\n${n}\n---\n### MANDATORY RULES:\n1. **LANGUAGE ADHERENCE**:\n - **DETECT** the language of the section labeled "CURRENT USER QUESTION" below.\n - **RESPOND ONLY** in that same language.\n - **IGNORE** any language bias from the context or history.\n2. **HISTORY CLEANING**:\n - If any assistant response in the conversation history says it **"doesn't know"**, **"doesn't have data"**, **"cannot find info"**, or similar, you MUST **IGNORE that specific history segment**. \n - Do not let previous data failures prevent you from answering the CURRENT USER QUESTION if the information is available now or in your core knowledge.\n3. **BREVITY**: Keep your answer extremely concise (under 3000 characters).\n4. **DATA INTEGRITY**: Do not mention data gaps or historical missing info; just answer based on available info.\n\n---\nCURRENT USER QUESTION:\n${e}\n---\n`,o="/api/gemini-cortex/proxy",a={model:"gemini-2.5-flash",data:{contents:[{parts:[{text:t}]}],tools:[{googleSearch:{}}]}};this.enableGoogleSearch||delete a.data.tools;const i=await this.post(o,a);return i?.data?.data?.candidates?.[0]?.content?.parts?.[0]?.text||i?.data?.candidates?.[0]?.content?.parts?.[0]?.text}catch(t){if((t?.message?.includes("search_grounding_request_per_project_per_day")||t?.data?.error?.message?.includes("search_grounding_request_per_project_per_day"))&&this.enableGoogleSearch)return this.enableGoogleSearch=!1,await this.generateContent(e,n);throw t}}async checkTypeQuestion(e,n){try{const t=n+`---\nCURRENT USER QUESTION:\n${e}\n---\n\nAnalyze this question and determine its category.\nIMPORTANT: The following topics should ALWAYS be classified as "yes" (crypto-related):\n- Greetings (in ANY language): hello, hi, xin chào, bonjour, etc.\n- Cryptocurrency, blockchain, crypto trading, DeFi, NFT\n- Wallet/Account questions (in ANY language): account, wallet, address, balance, portfolio, holdings\n- Registration/Sign-up questions (in ANY language): register, sign up, create account, create wallet, new account, new wallet, registration\n- Wallet access questions (in ANY language): open wallet, open account, start wallet, launch wallet, access wallet, access account\n- Token/coin questions: prices, market data, trading\n- Chain questions: ETH, Base, Optimism, BSC, Polygon, Arbitrum\n- Smart contracts, gas fees, transactions\n- Action phrases (in ANY language): send token, swap token, send nft, buy token, bridge token, info token, check balance, etc.\n\nCRITICAL: Detect these concepts in ANY language (English, Japanese, Chinese, Vietnamese, Korean, Spanish, etc.)\nThe user may ask in their native language, so recognize the MEANING, not just specific words.\n\nIf the question is about ANY of the above topics, respond with ONLY the word "yes" (lowercase, nothing else).\nOtherwise, respond with ONLY the word "no" (lowercase, nothing else).\nDo not provide any explanation or additional text.`,o="/api/gemini-cortex/proxy",a={model:"gemini-2.5-flash",data:{contents:[{parts:[{text:t}]}]}},i=await this.post(o,a);return i?.data?.data?.candidates?.[0]?.content?.parts?.[0]?.text||i?.data?.candidates?.[0]?.content?.parts?.[0]?.text}catch(t){throw t}}},aa="https://nft-demo.keyring.app";function ia(e,n,t){if(!e)return e;const o=e.toLowerCase().trim();if("max"===o||"all"===o)return n||e;const a=o.match(/^(\d+(?:\.\d+)?)%$/);if(a){const e=parseFloat(a[1])/100;return((parseFloat(n)||0)*e).toFixed(8).replace(/\.?0+$/,"")||"0"}const i=o.match(/^\$?(\d+(?:\.\d+)?)\$?$/);if(i&&(o.startsWith("$")||o.endsWith("$"))){const n=parseFloat(i[1]);return t&&t>0?(n/t).toFixed(8).replace(/\.?0+$/,"")||"0":e}return e}const ra=({isOpen:o,onClose:s,onTransaction:l,position:f="bottom-right",modalChatStyle:m={}})=>{const{t:h,ti:p}=w(),{messages:b,addMessage:g,updateMessageAction:y,updateMessageText:A,getMessageById:k,clearMessagesById:v}=function(){const{account:e}=Gt(),{t:n}=w(),t=(o=e?.address,s=e?.chainId,o&&s?`${o}_${s}`:"");var o,s;const c=d(()=>Zt(n("welcomeMessage")),[n]),[l,u]=a(()=>t||"pending"),[f,m]=a(()=>{const e=$t();return t?e&&e.owner===t?e.messages:Zt(n("welcomeMessage")):e?.messages??Zt(n("welcomeMessage"))});if("pending"===l&&t){const e=$t();e&&e.owner===t?m(e.messages):eo(t,f),u(t)}else"pending"!==l&&t&&l!==t&&(m(c),eo(t,c),u(t));const h=d(()=>f.map(e=>e.id===Kt?{...e,text:n("welcomeMessage")}:e),[f,n]);i(()=>{"pending"!==l&&eo(l,f)},[f,l]),i(()=>{const e=[];for(let n=0;n<Yt.length;n++){const t=Yt.key(n);t&&t.startsWith(jt+"_")&&e.push(t)}e.forEach(e=>Yt.removeItem(e))},[]);const p=r(()=>{m(c),eo(t,c)},[t,c]),b=r(e=>{m(n=>{const t=n.filter(n=>!e.includes(n.id));return t.length>Xt?t.slice(t.length-Xt):t})},[]);return{messages:h,setMessages:m,addMessage:(e,n,t,o,a)=>{const i=t?f.find(e=>e.id===t):void 0,r={id:Math.random().toString(36).substring(2,12),text:e,sender:n,timestamp:/* @__PURE__ */new Date,...i&&{replyTo:{id:i.id,text:i.text,sender:i.sender}},...o&&{buttons:o},...a&&{actionData:a}};return m(e=>{const n=[...e,r];return n.length>Xt?n.slice(n.length-Xt):n}),r},updateMessageAction:(e,n)=>{m(t=>t.map(t=>t.id===e&&t.actionData?{...t,actionData:{...t.actionData,status:n}}:t))},updateMessageText:(e,n)=>{m(t=>t.map(t=>t.id===e?{...t,text:n}:t))},getMessageById:e=>f.find(n=>n.id===e),clearMessages:p,clearMessagesById:b}}(),[C,T]=a(""),[E,I]=a(!1),[x,S]=a(!0),[N,B]=a(null),R=u(null),D=u(null),U=u(null),F=u(null),O=u(null),L=u(!1),M=u(x);i(()=>{M.current=x},[x]);const{account:P,chainData:H,chainType:Y,chainTypeMoralis:J,chainId:q,isChainSupported:V}=Gt(),{config:W}=(()=>{const e=c(no);if(!e)throw new Error("useConfig must be used within ConfigProvider");return e})(),G=q&&W?.rpcUrls?.[q]||void 0,z=r(()=>{const e=Yt.getItem("dataBuyToken");if(e)try{return JSON.parse(e)}catch{return{srcTokenAddress:"",descTokenAddress:"",amount:"",srcTokenDecimals:18,descTokenDecimals:18}}return{srcTokenAddress:"",descTokenAddress:"",amount:"",srcTokenDecimals:18,descTokenDecimals:18}},[]),Q=r(e=>{Yt.setItem("dataBuyToken",JSON.stringify(e))},[]),j=r(e=>{const n={...z(),...e};Q(n)},[z,Q]),X=r(e=>{B(e),ta.isDesktop&&U.current?.focus()},[]),K=r(async(e,n)=>{j({descTokenAddress:e,descTokenDecimals:n||18});try{I(!0);const e=await xo({address:P?.address||"",chain:J});if(e?.success&&e?.data?.result){const n=e.data.result;if(n?.length>0){const e=n.map(e=>({id:e.token_address,text:`${e.name}: ${e.balance_formatted} ${e.symbol} ($${vo(e.usd_value||0)?.decimalPlaces(2).toFormat()||"0"})`,value:p("buttonBuyWith",{symbol:e.symbol}),action:"click_balance_item_user_to_buy_button",fullWidth:!0,extraData:{tokenAddress:e.token_address,symbol:e.symbol,balance:e.balance_formatted,usdValue:e.usd_value,decimals:e.decimals}}));g(p("walletBalanceSpendable",{chain:H?.name||"unknown"}),"bot",void 0,e)}else g(p("walletNoTokensFound",{chain:H?.name||"unknown"}),"bot")}else g(h("walletFetchFailed"),"bot")}catch(t){g(h("walletFetchError"),"bot")}finally{I(!1)}},[j,P?.address,J,g,H?.name,h,p]),Z=r(async(e,n,t,o)=>{j({srcTokenAddress:e,srcTokenDecimals:o||18});let a=t||"0";if(e===Vt)try{const e=await Ko({chainId:q,rpcUrl:G});if(e.isGreaterThan(0)){const n=e.times(1e6),i=new vo(qt(t,o||18).toString()).minus(n);a=i.isGreaterThan(0)?vo(ge(BigInt(i.toFixed(0)),18)).toFixed():"0"}}catch(r){}const i=[25,50,75,100].map(t=>({id:`percent-${t}`,text:`${t}%`,value:p("buttonUsePercent",{percent:String(t),symbol:n}),action:"select_percent",extraData:{percent:t,tokenAddress:e,tokenSymbol:n,tokenDecimals:o||18,tokenBalance:a}}));vo(a).isZero()?g(p("insufficientFeeToken",{symbol:n}),"bot"):g(p("selectAmountOf",{symbol:n,balance:a}),"bot",void 0,i)},[g,q,G,j,p]),_=r(async(e,n,t,o)=>{const a={amount:(parseFloat(n)*(e/100)).toFixed(6)};void 0!==t&&(a.srcTokenAddress=t),void 0!==o&&(a.srcTokenDecimals=o),j(a);const i=z(),r=qt(i.amount,i.srcTokenDecimals||18).toString(),s=await Do({chainId:q,tokenIn:i.srcTokenAddress,tokenInAmount:r,tokenOut:i.descTokenAddress,tokenOutRecipient:P?.address||"",slippage:"auto",accesstoken:"d6c45897b8f6"});if(s.success&&s.data){const e=s.data,n=e.tokenIn,t=e.tokenOut,o=vo(ge(BigInt(n.amount||0),n.decimals)).decimalPlaces(6).toFormat(),a=vo(ge(BigInt(t.amount||0),t.decimals)).decimalPlaces(6).toFormat();let l=!1;if(i.srcTokenAddress!==Vt&&""!==i.srcTokenAddress&&P?.address&&e.tx?.to)try{const n=await zo({tokenAddress:i.srcTokenAddress,ownerAddress:P.address,spenderAddress:e.tx.to,chainId:q,rpcUrl:G});l=vo(n.toString()).isLessThan(r)}catch(c){l=!0}const d=e.estimatedTransactionFee?.total?vo(e.estimatedTransactionFee.total):vo(0);let u=vo(0);if(l&&P?.address)try{const n=Qo({tokenAddress:i.srcTokenAddress,spenderAddress:e.tx?.to||"",fromAddress:P.address,chainId:q,amount:r});u=await Xo({from:P.address,to:n.to,data:n.data,chainId:q,rpcUrl:G})}catch(c){}const f=d.plus(u),m=H?.nativeCurrency?.symbol||"native";let w="",b=!1;if(P?.address&&f.isGreaterThan(0))try{const e=await jo({address:P.address,chainId:q,rpcUrl:G});if(e.isLessThan(f)){b=!0;const n=vo(ge(BigInt(e.toFixed(0)),18)).decimalPlaces(6).toFormat(),t=vo(ge(BigInt(f.toFixed(0)),18)).decimalPlaces(6).toFormat();w=p("swapFeeWarning",{symbol:m,balance:n,needed:t})}}catch(c){}const y=`From: ${o} ${n.symbol}\n⬇️\nTo: ${a} ${t.symbol}\n\n`+w+"\n";if(b)g(y,"bot");else if(l){const t=y+p("swapNeedApprove",{symbol:n.symbol}),o=[{id:"approve-for-swap",text:p("swapApproveButton",{symbol:n.symbol}),value:p("swapApproveValue",{symbol:n.symbol}),action:"approve_for_swap",fullWidth:!0,extraData:{tokenAddress:i.srcTokenAddress,spenderAddress:e.tx.to,tokenSymbol:n.symbol,amountInWei:r,tx:e.tx}}];g(t,"bot",void 0,o)}else{const n=[{id:"confirm-swap",text:h("swapConfirmButton"),value:h("swapConfirmValue"),action:"confirm_swap",extraData:{tx:e.tx}}];g(y+h("swapReadyToProceed"),"bot",void 0,n)}}else g(p("swapEstimationError",{error:s.errorMessage||s.error||"Unknown error"}),"bot")},[z,j,g,q,P?.address,H?.nativeCurrency?.symbol,G,h,p]),$=r(async(e,n,t)=>{try{if("suggested_action"===n)return F.current=e,void T(e);if(g(e,"user"),S(!1),I(!0),n)switch(await Lt(500),n){case"click_buy_item_token_button":await K(t?.tokenAddress||"",t?.decimals||18);break;case"click_balance_item_user_to_buy_button":await Z(t?.tokenAddress||"",t?.symbol||"",t?.balance||"",t?.decimals||18);break;case"select_percent":await _(t?.percent||0,t?.tokenBalance||"",t?.tokenAddress||void 0,t?.tokenDecimals||void 0);break;case"confirm_swap":if(t?.tx&&l){const e=t.tx,n={from:P?.address||"",to:e.to,data:e.data,value:e.value,chainId:q},i=g(h("txProcessing"),"bot");try{I(!1);const e=await l(n);if("success"===e.status&&e.transactionHash){const n=H?.blockExplorers?.default?.url,t=n?`\n[View on Explorer](${n}/tx/${e.transactionHash})`:`\nTx: ${e.transactionHash}`;A(i.id,h("txSubmitted")+t);try{await Lt(2e3),"success"===(await Go({transactionHash:e.transactionHash,chainId:q||1,rpcUrl:G})).status?A(i.id,h("txConfirmedSwap")+t):A(i.id,h("txRevertedSwap")+t)}catch(o){A(i.id,h("txTimeout")+t)}}else if("success"===e.status)A(i.id,h("txSuccessfulSwap"));else{const n=e.error?`\nError: ${e.error}`:"";A(i.id,h("txFailed")+n)}}catch(a){A(i.id,h("txFailed"))}}else g(h("txDataNotAvailable"),"bot");break;case"approve_for_swap":{const e=t?.tokenAddress||"",n=t?.spenderAddress||"",i=t?.tokenSymbol||"token",r=t?.tx;if(!e||!n||!l){g(h("approvalDataNotAvailable"),"bot");break}const s=t?.amountInWei||void 0,c=Qo({tokenAddress:e,spenderAddress:n,fromAddress:P?.address||"",chainId:q,tokenSymbol:i,amount:s}),d={from:c.from,to:c.to,data:c.data,value:c.value,chainId:c.chainId};g(p("approving",{symbol:i}),"bot");try{I(!1);const e=await l(d);let n="success"===e.status;if("success"===e.status&&e.transactionHash)try{n="success"===(await Go({transactionHash:e.transactionHash,chainId:q||1,rpcUrl:G})).status}catch(o){n=!0}if(n){g(p("approvalSuccess",{symbol:i}),"bot");const e=[{id:"confirm-swap-after-approve",text:h("confirmSwapButton"),value:h("swapConfirmValue"),action:"confirm_swap",fullWidth:!0,extraData:{tx:r}}];g(h("approvalConfirmSwap"),"bot",void 0,e)}else{const n=e.error?`\nError: ${e.error}`:"";g(h("approvalFailed")+n,"bot")}}catch(a){g(h("approvalFailed"),"bot")}break}case"click_swap_dest_token":{const e=t?.tokenAddress||"",n=t?.symbol||"";j({descTokenAddress:e,descTokenDecimals:t?.decimals||18});const o=z(),a=o.srcTokenAddress||"",r=a===Vt;try{const e=await xo({address:P?.address||"",chain:J});if(e?.success&&e?.data?.result){const t=e.data.result;let i="",s="0";if(r){const e=t.find(e=>e.native_token);i=H?.nativeCurrency?.symbol||"ETH",s=e?.balance_formatted||"0"}else{const e=t.find(e=>e.token_address.toLowerCase()===a.toLowerCase());e&&(i=e.symbol,s=e.balance_formatted)}if(i&&parseFloat(s)>0){const e=[25,50,75,100],t=o.srcTokenDecimals||18,r=e.map(e=>({id:`percent-${e}`,text:`${e}%`,value:p("buttonUsePercent",{percent:String(e),symbol:i}),action:"select_percent",extraData:{percent:e,tokenAddress:a,tokenSymbol:i,tokenDecimals:t,tokenBalance:s}}));g(p("swapSelectAmount",{from:i,to:n,balance:s}),"bot",void 0,r)}else g(h("swapNoSourceToken"),"bot")}else g(h("couldNotFetchBalance"),"bot")}catch(i){g(h("couldNotLoadBalance"),"bot")}break}case"select_nft_to_send":{const e=t?.name||"NFT",n=t?.contractAddress||"",o=t?.tokenId||"",a=t?.tokenStandard||"ERC721",i=t?.amount||"1",r=t?.image||"",s={contract_address:n,token_id:o,to_address:t?.toAddress||"",token_standard:a,amount:"1",maxAmount:i,nft_name:e};g(p("nftSendReview",{name:e,standard:a,tokenId:o}),"bot",void 0,void 0,{action:"send_nft",parameters:s,status:"pending",nftInfo:{name:e,image:r||void 0,tokenId:o,contractAddress:n,tokenStandard:a}});break}default:g(p("actionExecutedFor",{action:n,value:e}),"bot")}else await Lt(500),g(p("receivedButtonValue",{value:e}),"bot");I(!1),ta.isDesktop&&U.current?.focus()}catch(a){g(h("errorProcessingRequest"),"bot"),I(!1)}},[P?.address,g,A,H?.blockExplorers?.default?.url,H?.nativeCurrency?.symbol,q,J,z,K,Z,l,_,j,G,h,p]),ee=r(async()=>{try{I(!0);const e=H?.tokenTrendingDefault||[],[n,t]=await Promise.allSettled([Bo.getTopGainers(Y,"24h",5),Bo.getTokensDetails(e,Y)]);let o=[];"fulfilled"===n.status&&n.value?.data&&(o=[...n.value.data]),"fulfilled"===t.status&&t.value?.data&&(o=[...t.value.data,...o]),o=o.filter((e,n,t)=>n===t.findIndex(n=>n.address.toLowerCase()===e.address.toLowerCase()));const a=o.map(e=>({id:e?.symbol,text:e?.symbol,value:p("buttonBuyToken",{name:e.name,symbol:e?.symbol||""}),action:"click_buy_item_token_button",extraData:{tokenAddress:e?.address||"",symbol:e?.symbol||"",decimals:e?.decimals||18}}));await Lt(1e3),I(!1),g(p("trendingTokensHeader",{chain:H?.name||"Unknown"}),"bot");const i=o.map((e,n)=>`${n+1}. ${e.name} (${e?.auditGoplus?.token_symbol||e.symbol||"Unknown"})\n$${vo(e?.price||0).decimalPlaces(4).toFormat()} (${e.price_change_percentage_24h||e.priceChange}%)\n\n---\n`).join("\n");g(`${i}${h("trendingTokensQuestion")}`,"bot",void 0,a)}catch(e){g(h("trendingTokensError"),"bot")}finally{I(!1)}},[g,H?.name,H?.tokenTrendingDefault,Y,h,p]),ne=r(async(e={})=>{const{numberOfView:n=5}=e;try{I(!0);const e=await No({address:P?.address||"",chain:J,limit:100,exclude_spam:!1});if(e?.success&&e?.data?.result&&e.data.result.length>0){const t=e.data.result;let o=e.data.result;n&&n>0&&(o=o.slice(0,n));const a=o.map(e=>{const n=e.normalized_metadata?.name||e.name||`#${e.token_id}`,t=e.normalized_metadata?.image||e.media?.original_media_url||"";return{id:`${e.token_address}-${e.token_id}`,text:`${n} (${e.symbol||e.contract_type}) - ${e.token_id}`,value:p("buttonSendNft",{name:n}),action:"select_nft_to_send",fullWidth:!0,extraData:{contractAddress:e.token_address,tokenId:e.token_id,tokenStandard:e.contract_type,name:n,symbol:e.symbol,amount:e.amount,image:t}}}),i=o.map((e,n)=>{const t=e.normalized_metadata?.name||e.name||`#${e.token_id}`,o="ERC1155"===e.contract_type?` (x${e.amount})`:"",a=e.normalized_metadata?.image||e.media?.original_media_url||"";return`${n+1}. ${a?`![${t}](${a})\n`:"🖼️ "}**${t}**${o}\n ${e.symbol||e.contract_type} | Token ID: ${e.token_id}`}).join("\n\n");await Lt(500),I(!1),g(`${p("nftCollectionHeader",{count:String(o.length),list:i})}${n&&n>0&&t.length>n?p("nftMoreItems",{count:String(t.length-n)}):""}${h("nftSelectBelow")}`,"bot",void 0,a),n&&n>0&&t.length>n&&g(p("sendOtherNfts",{link:aa}),"bot")}else I(!1),g(h("nftNoCollection"),"bot")}catch(t){I(!1),g(h("nftFetchError"),"bot")}},[P?.address,J,g,h,p]),te=r(async()=>{try{I(!0);const e=await xo({address:P?.address||"",chain:J});if(e?.success&&e?.data?.result&&e.data.result.length>0){const n=e.data.result,t=n.flatMap(e=>[{id:`send-${e.token_address}`,text:p("buttonSendToken",{symbol:e.symbol}),value:p("buttonSendToken",{symbol:e.symbol}),action:"suggested_action",fullWidth:!!ta.isMobile},{id:`buy-more-${e.token_address}`,text:p("buttonBuyMoreToken",{symbol:e.symbol}),value:p("buttonBuyMoreToken",{symbol:e.symbol}),action:"suggested_action",fullWidth:!!ta.isMobile}]),o=n.map((e,n)=>{const t=void 0!==e.usd_value?` ≈ $${vo(e.usd_value).decimalPlaces(2).toFormat()}`:"";return`${n+1}. **${e.name}** (${e.symbol})\n Balance: ${e.balance_formatted}${t}`}).join("\n\n");await Lt(500),I(!1),g(p("viewBalancesHeader",{chain:H?.name||"this chain",list:o}),"bot",void 0,t)}else I(!1),g(h("viewBalancesEmpty"),"bot")}catch(e){I(!1),g(h("viewBalancesFetchError"),"bot")}},[P?.address,J,g,H?.name,h,p]),oe=d(()=>[{id:"ask",icon:"❓",text:h("suggestionAskText"),action:async()=>{S(!1),I(!0),g(h("suggestionAskUserMessage"),"user"),await Lt(1e3),I(!1),g(h("suggestionAskBotReply"),"bot")}},{id:"buy",icon:"💰",text:h("suggestionBuyText"),action:async()=>{S(!1),g(h("suggestionBuyText"),"user"),Pn(P?.address||"")&&V?await ee():(I(!0),await Lt(1e3),Pn(P?.address||"")&&!V?g(h("walletConnectedChainUnsupported"),"bot"):g(h("walletNotConnected"),"bot"),I(!1))}}],[g,P?.address,ee,h,V]),ae=e=>{if(0===e)return!0;const n=b[e],t=b[e-1],o=new Date(n.timestamp),a=new Date(t.timestamp);return o.setHours(0,0,0,0),a.setHours(0,0,0,0),o.getTime()!==a.getTime()};i(()=>{R.current?.scrollIntoView({behavior:"smooth"})},[b]),i(()=>{o?(U.current&&ta.isDesktop&&U.current.focus(),R.current?.scrollIntoView({behavior:"instant"}),L.current&&O.current?Date.now()-O.current>3e5&&S(!0):S(!0),O.current=null,L.current=!1,setTimeout(()=>{R.current?.scrollIntoView({behavior:"smooth"})},50)):(O.current=Date.now(),L.current=!M.current)},[o]),i(()=>{const e=e=>{"Escape"===e.key&&o&&s()};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[o,s]);const re=r(async()=>{if(""===C?.trim()||E)return;const e=N,n=g(C?.trim(),"user",N?.id);T(""),B(null),I(!0),S(!1),I(!0);try{let l,d;const u=b.slice(-20);let f="";if(u.length>0){f="\n\n## CONVERSATION HISTORY:\n";for(const e of u)"user"===e.sender?f+=`User: ${e.text}\n`:f+=`Assistant: ${e.text.length>400?e.text.substring(0,400)+"...":e.text}\n`;f+="\n---\n"}let m=C?.trim();e&&(m=`[Replying to ${"user"===e.sender?"my previous":"your"} message: "${e.text}"]\n\n${m}`);try{const e=await oa.checkTypeQuestion(m,f);if(e?.startsWith("no")){const e=await oa.generateContent(m,f);let n=null;try{let t=e?.trim();t.startsWith("```json")?t=t.replace(/^```json\s*/,"").replace(/\s*```$/,""):t.startsWith("```")&&(t=t.replace(/^```\s*/,"").replace(/\s*```$/,"")),n=JSON.parse(t)}catch{n=null}return I(!1),void g(n?.message||e,"bot")}}catch(o){}if(P?.address&&V)try{const[e,n]=await Promise.allSettled([xo({address:P.address,chain:J}),No({address:P.address,chain:J,limit:100,exclude_spam:!0})]);"fulfilled"===e.status&&e.value?.success&&e.value?.data?.result&&(l=e.value.data.result.map(e=>({symbol:e.symbol,name:e.name,balance_formatted:e.balance_formatted,usd_value:e.usd_value,native_token:e.native_token,token_address:e.token_address}))),"fulfilled"===n.status&&n.value?.success&&n.value?.data?.result&&(d=n.value.data.result.map(e=>({name:e.normalized_metadata?.name||e.name||`#${e.token_id}`,token_address:e.token_address,token_id:e.token_id,contract_type:e.contract_type||"",amount:e.amount||"1"})))}catch{}const w=function(e){const{walletAddress:n,chainName:t,chainId:o,nativeSymbol:a,walletTokens:i,walletNfts:r}=e;return n?n&&!Ut[o]?`You are a Web3 wallet assistant for the Keyring crypto EVM wallet app.\n The user's wallet address is: ${n}\n The user is selected on (chainId: ${o}) an UNSUPPORTED chain.\n\n ## YOUR ROLE:\n - You are a friendly, knowledgeable assistant that can talk about ANY topic naturally\n - You can freely answer general questions, discuss crypto tokens, prices, market info, token details, etc. — these do NOT require a supported chain\n - **BLOCKED on unsupported chain** — if the user asks for any of the following, politely inform them that chain (chainId: ${o}) is not currently supported and the action cannot be performed:\n - Checking THEIR OWN balance ("what is my balance?", "how much ETH do I have?")\n - Sending tokens or NFTs\n - Swapping or buying tokens\n - Approving token spending\n - Wrapping/unwrapping tokens\n - Viewing or transferring their NFT collection\n - Any action that reads or writes to their wallet on the current chain\n - **ALLOWED on unsupported chain** — respond normally and helpfully for:\n - General questions (weather, coding, history, math, etc.)\n - Token information, prices, market data, token details\n - Any query that does NOT require interacting with the user's wallet on the current chain\n - Respond in the same language the user uses\n\n ## RESPONSE FORMAT:\n Always respond with a valid JSON object:\n {"action":"chat","message":"<your response>", suggested_actions:[{"label":"<short button text>","prompt":"<message sent when clicked>"}]}\n\n ## RULES:\n - suggested_actions: include when your message offers the user interactive choices or asks a follow-up question. NEVER include suggested_actions that ask the user to connect their wallet (e.g., "Connect wallet", "Connect now", etc.) — the app handles wallet connection separately\n - **CRITICAL**: NEVER include any "Buy" actions (e.g., "Buy USDC", "Buy ETH", "Purchase token", etc.) in suggested_actions. The app handles Buy buttons separately. Only include non-buy actions in suggested_actions (e.g., "Send token", "Swap token", "Check balance", "Show my NFTs").\n - For wallet-required actions, politely explain the user needs to connect their wallet first, and put this in the "message" field\n - ALWAYS respond with raw JSON only, never wrap in \`\`\`json code blocks\n - **CRITICAL - LANGUAGE**: Always respond in the SAME language the user writes in. English → English. Vietnamese → Vietnamese. NEVER use Chinese or any other language unless the user wrote in that language.`:`You are a Web3 wallet assistant for the Keyring crypto EVM wallet app.\nThe user's wallet address is: ${n}\nThe user is on chain: ${t} (chainId: ${o})\nNative token: ${a}${i&&i.length>0?`\n## USER'S CURRENT WALLET BALANCE:\n${i.map(e=>{const n=void 0!==e.usd_value?` (~$${e.usd_value.toFixed(2)})`:"";return`- ${e.name} (${e.symbol}): ${e.balance_formatted}${n}${e.native_token?" [native]":` [${e.token_address}]`}`}).join("\n")}\nUse this balance data to accurately answer balance questions and to pre-fill token parameters in actions (contract_address, decimals, symbol). NEVER ask the user to provide token info that is already available above.\n`:""}${r&&r.length>0?`\n## USER'S NFT COLLECTION:\n${r.map(e=>{const n="ERC1155"===e.contract_type?` (x${e.amount})`:"";return`- ${e.name}${n} | ${e.contract_type} | contract: ${e.token_address} | tokenId: ${e.token_id}`}).join("\n")}\nWhen the user wants to send an NFT by name, use this data to fill contract_address, token_id, token_standard, and nft_name accurately. NEVER guess or fabricate NFT contract addresses.\n`:""}\n## YOUR ROLE:\n- You are a friendly, knowledgeable assistant that can talk about ANY topic naturally\n- You also specialize in crypto wallet operations: send tokens, swap, approve, check balances, get token info\n- When user requests a wallet action, return a structured JSON so the app can build the transaction\n- When user asks about general topics (weather, coding, history, math, etc.), respond naturally using the "chat" action\n- You will receive CONVERSATION HISTORY to maintain context. Use it to understand what the user is referring to\n- NEVER confuse a general conversation with a wallet action. Only use wallet actions when user EXPLICITLY wants to perform a crypto operation\n- **CRITICAL: For ERC20 token actions (send_token, swap_token, buy_token, approve_token), contract_address is a REQUIRED field — you MUST always include it in the JSON response with the ACTUAL contract address on the current chain (chainId: ${o}). NEVER leave it empty. You MUST look up and provide the correct contract address for the token on this chain. You know common tokens like USDC, USDT, DAI, WETH, LINK, UNI, AAVE, etc. on major chains — always provide the correct address. If the token genuinely does not exist on this chain, inform the user instead of proceeding with the action. EXCEPTION: For send_nft, contract_address is OPTIONAL — if the user refers to an NFT by name and you don't know the contract address, leave it as empty string "" and fill nft_name instead. NEVER make up or guess NFT contract addresses.**\n- **CRITICAL ACTION RULE: When user requests a wallet operation (swap, send, buy, approve, wrap, unwrap), you MUST return that action type IMMEDIATELY — even if some parameters are missing. DO NOT return a "chat" action to ask for missing details. Simply leave the missing parameters as empty string "". Your prompt for more info (e.g., asking for recipient address) goes in the "message" field of the wallet action itself. For example: If user says "swap DAI to USDC", you MUST return {"action":"swap_token",...} directly, NOT {"action":"chat",...}. If user says "send WETH", you MUST return {"action":"send_token","parameters":{"contract_address":"<WETH address>","to_address":"","amount":"","decimals":"18","token_symbol":"WETH"}} with empty to_address and amount, NOT a chat response.**\n\n## RESPONSE FORMAT:\nYou MUST respond with a valid JSON object in this exact format. Do NOT wrap it in markdown code blocks.\n\n### For Web3 actions (send, swap, approve, wrap, unwrap):\n{\n "action": "<action_type>",\n "message": "<your friendly explanation to the user>",\n "parameters": {\n "<param_key>": "<value or empty string if unknown>"\n }\n}\n\n### For information queries (balance, token info) or normal conversation:\n{\n "action": "chat",\n "message": "<your response text here>",\n "parameters": {},\n "token_mentions": [],\n "suggested_actions": []\n}\n\n### IMPORTANT - suggested_actions field:\nWhenever your response contains a follow-up question or offers the user an interactive choice (e.g., "Would you like me to...", "If you want, I can...", "Do you want to..."), you MUST include a "suggested_actions" array with clickable button options so the user can quickly respond.\nEach entry: { "label": "<short button text>", "prompt": "<full message to send when clicked>" }\nRules for suggested_actions:\n- Include suggested_actions ONLY when your message explicitly offers the user a choice or asks a follow-up question\n- Each button should represent one distinct option the user can take\n- "label" should be short (2-6 words) — this is the button text displayed to the user\n- "prompt" should be the full user message that will be sent when the button is clicked\n- Maximum 4 suggested actions per response\n- suggested_actions should be an empty array [] when your message does NOT offer any interactive choices\n- You can include suggested_actions in BOTH "chat" responses and wallet action responses (in the latter case, for follow-up options after the action message)\n- Do NOT add suggested_actions for simple statements or answers that don't ask the user anything\n- **CRITICAL**: NEVER include any "Buy" actions (e.g., "Buy USDC", "Buy ETH", "Purchase token", etc.) in suggested_actions. The app handles Buy buttons separately through token_mentions. Only include non-buy actions in suggested_actions (e.g., "Send WBTC", "Swap WBTC to ...", "Check balance", "Show my NFTs").\n\n### IMPORTANT - token_mentions field:\nWhenever your "chat" response mentions, lists, or discusses specific tokens/coins (e.g., trending tokens, token details, token recommendations, price discussions, asking about a token), you MUST include a "token_mentions" array with each token's info so the user can quickly buy them.\nEach entry: { "symbol": "<TOKEN_SYMBOL>" (REQUIRED), "contract_address": "<actual address>" (REQUIRED), "decimals": <number> (REQUIRED) }\n- You MUST include ALL crypto tokens mentioned in your response in token_mentions.\n- You MUST provide the actual contract_address for each token on chainId ${o}. NEVER leave contract_address empty.\n- You MUST provide the accurate decimals for each token.\n- Only include tokens that are actual tradeable crypto tokens mentioned in your response\n- Do NOT include token_mentions for general greetings, non-crypto conversations, or balance checks\n- If you do not know the contract address for a token on this chain, still include it in token_mentions but you MUST try your best to provide the correct address. The app needs the address to function.\n- token_mentions should be an empty array [] ONLY when no specific crypto tokens are discussed at all\n\n## SUPPORTED ACTIONS:\n\n### 1. send_native - Send native token (${a})\nParameters: { "to_address": "", "amount": "" }\nTriggered by: "send ${a}", "transfer 0.1 ${a} to 0x...", "send native token"\n**IMPORTANT**: ONLY use send_native when the user explicitly wants to send **${a}** (the native token of the CURRENT chain). If the user says "send ETH" but the current chain's native token is NOT ETH (e.g., on Polygon where native is MATIC), then ETH is an ERC20 token on this chain — use send_token with the correct ETH/WETH contract address instead. NEVER use send_native for a token that is not ${a}.\nNote: If user says "max", "all", or "send everything", set amount to "max". If user says "X%" (e.g., 50%), set amount to "50%". If user specifies a USD/dollar amount (e.g., "send $5 of ETH", "send 0.01$ eth"), set amount to "$5" or "$0.01". The app resolves these to actual token values using the token's USD price.\n\n### 2. send_token - Send ERC20 token\nParameters: { "contract_address": "" (REQUIRED), "token_symbol": "", "to_address": "", "amount": "", "decimals": "" }\nTriggered by: "send USDC", "transfer 100 DAI to 0x...", "send token"\nNote: contract_address is REQUIRED — you MUST always provide the actual contract address of the token on chainId ${o}. NEVER leave it empty. ALWAYS provide accurate decimals for the token. If user says "max", "all", or "send everything", set amount to "max". If user says "X%" (e.g., 50%), set amount to "50%". If user specifies a USD/dollar amount (e.g., "send $5 of ETH", "send 0.01$ USDC", "transfer $100 worth of DAI"), set amount to the dollar string with $ prefix like "$5", "$0.01", "$100". The app resolves these to actual token values using the token's USD price.\n\n### 3. swap_token - Swap tokens\nParameters: { "token_in": "<contract_address or 'native'>" (REQUIRED), "token_in_symbol": "", "token_in_decimals": "", "token_out": "<contract_address>" (REQUIRED), "token_out_symbol": "", "token_out_decimals": "", "amount": "" }\nTriggered by: "swap ETH to USDC", "exchange 0.5 ETH for USDC", "convert ETH to USDC", "swap token", "I want to swap", "đổi token"\nNote: token_in and token_out are REQUIRED fields — MUST contain the actual contract address. For native tokens (${a}), set token_in to "native". For ERC20 tokens, you MUST provide the correct contract address on chainId ${o}. NEVER leave empty. ALWAYS fill in token_in_symbol, token_out_symbol, token_in_decimals, and token_out_decimals with accurate values for each token. If user says "max", "all", or "swap everything", set amount to "max". If user says "X%" (e.g., 50%), set amount to "50%". If user specifies a USD/dollar amount (e.g., "swap $10 of ETH to USDC"), set amount to "$10". The app resolves these to actual token values using the token's USD price.\n**IMPORTANT**: If the user says "swap" or "I want to swap" WITHOUT specifying any tokens or amounts, still return swap_token with ALL parameters as empty strings "". The app will show the user's wallet balances so they can pick a token.\n\n### 4. buy_token - Buy a token (user wants to purchase a specific token)\nParameters: { "token_symbol": "", "contract_address": "" (REQUIRED), "decimals": "" }\nTriggered by: "buy USDC", "I want to buy ETH", "purchase DOGE", "mua token X"\nNote: Use this when user says "buy <token>" without specifying what to sell. If user specifies both tokens ("buy USDC with ETH"), use swap_token instead. contract_address is REQUIRED — you MUST always provide the actual contract address on chainId ${o}. NEVER leave it empty. If the token does not exist on this chain, inform the user. For example, BNB is not native to most chains except BSC. ALWAYS provide accurate decimals for the token.\n\n### 5. approve_token - Approve token spending\nParameters: { "contract_address": "" (REQUIRED), "token_symbol": "", "spender_address": "", "amount": "", "decimals": "" }\nTriggered by: "approve USDC", "allow spending", "approve contract"\nNote: ALWAYS provide accurate decimals for the token.\n\n### 6. wrap_native - Wrap native token (${a} → W${a})\nParameters: { "amount": "" }\nTriggered by: "wrap ETH", "convert to WETH"\n\n### 7. unwrap_native - Unwrap native token (W${a} → ${a})\nParameters: { "amount": "" }\nTriggered by: "unwrap WETH", "convert WETH to ETH"\n\n### 8. send_nft - Send/Transfer an NFT (ERC721 or ERC1155)\nParameters: { "contract_address": "" (OPTIONAL), "token_id": "" (OPTIONAL), "to_address": "" (REQUIRED), "token_standard": "ERC721 or ERC1155" (OPTIONAL), "amount": "" (for ERC1155 only, default 1), "nft_name": "" }\nTriggered by: "send NFT", "transfer NFT #1234 to 0x...", "send my Bored Ape to...", "transfer ERC1155 token"\nNote: token_standard is OPTIONAL. If the user specifies the standard or you confidently know it, include "ERC721" or "ERC1155". Otherwise, leave it as empty string "" — the app will automatically detect the correct standard by querying on-chain metadata. For ERC1155, amount defaults to "1" if not specified. **IMPORTANT**: For NFTs, you typically do NOT know the contract_address. If the user refers to an NFT by name (e.g., "send Shou Rikuto", "send my Bored Ape"), leave contract_address as empty string "" and put the NFT name in nft_name — the app will look it up from the user's wallet. Only provide contract_address if the user explicitly gives the contract address. NEVER make up or guess NFT contract addresses.\n\n### 9. view_nfts - View/Show user's NFT collection\nParameters: {} (empty)\nTriggered by: "show my NFTs", "what NFTs do I have?", "view my NFT collection", "xem NFT của tôi", "list my NFTs"\nNote: Use this when user wants to VIEW or LIST their NFTs. Do NOT use "chat" action for NFT viewing requests.\n\n### 10. view_balances - View/Show user's full token balances\nParameters: {} (empty)\nTriggered by: "show my balances", "what tokens do I have?", "list my tokens", "view my wallet", "xem balance của tôi", "xem token của tôi", "show all my tokens", "what's in my wallet?"\nNote: Use this when user wants to see ALL their tokens/balances at once. Do NOT use "chat" action for wallet balance viewing requests. For single-token balance queries ("how much ETH do I have?", "check my USDC balance"), use "chat" action instead.\n\n### 11. chat - Normal conversation, token info\nParameters: {} (empty)\nOptional: token_mentions: [{ "symbol": "", "contract_address": "", "decimals": <number> }] — include when your response mentions specific tokens\nTriggered by: questions, greetings, info requests, balance checks, token details, trending tokens\n\n## CONTRACT ADDRESS ACCURACY REQUIREMENTS:\nYou have comprehensive, precise knowledge of token contract addresses on ALL major EVM chains. You MUST use this knowledge accurately.\n\n## RULES:\n1. Extract ALL mentioned values from the user's message and fill the parameters\n2. Leave parameter as empty string "" if the user didn't mention it\n3. Always include a friendly "message" explaining what you understood\n4. For "chat" action, put your full response in the "message" field\n5. **CRITICAL**: For ERC20 token actions, contract_address is a REQUIRED field — ALWAYS provide the ACTUAL contract address on chainId ${o}. NEVER leave it empty. You must know the correct addresses for common tokens (USDC, USDT, DAI, WETH, LINK, UNI, AAVE, etc.) on major chains. If a token does not exist on this chain, inform the user instead of proceeding. Be especially careful with tokens that are native to other chains (e.g., BNB is BSC native — if user asks to buy BNB on OP Mainnet, inform them it may not be available as an ERC20 on this chain). **EXCEPTION: For send_nft, if you don't know the NFT contract address, leave it as empty string "" and provide nft_name instead. NEVER fabricate NFT addresses.**\n6. **IMPORTANT**: ALWAYS provide accurate decimals for each token. This is CRITICAL for accurate transaction amounts.\n7. **IMPORTANT**: ALWAYS provide accurate token_symbol for each token. Even if the user only provides a contract address without naming the token, you MUST identify the token from the address and fill in token_symbol and decimals. For example: if user provides "0x4200000000000000000000000000000000000006" on OP/Base, you know it is WETH with decimals 18 — fill in token_symbol:"WETH" and decimals:"18". You have comprehensive knowledge of well-known token contract addresses — use it to populate all fields.\n8. For amounts, use the exact number the user mentioned (don't convert units). If user says "max", "all", or "everything", set amount to "max". If user says "X%" (e.g., "send 50% of my USDC", "swap 25% of my ETH"), set amount to "50%" or "25%" — the literal percentage string. If user specifies a USD/dollar amount (e.g., "send $5 of ETH", "send 0.01$ eth", "transfer $100 worth of USDC"), set amount to the dollar string with $ prefix like "$5", "$0.01", "$100" — the app will convert to the actual token amount using the token's USD price. The app resolves all these special formats to actual balance values.\n9. For native token sends, use "send_native" ONLY when the user wants to send **${a}** — the ACTUAL native token of the current chain (chainId: ${o}). If the user says "send ETH" but the native token on this chain is not ETH (e.g., Polygon where native is MATIC), treat ETH as an ERC20 token and use "send_token" with the correct ETH/WETH contract address on this chain. NEVER use send_native for a token symbol that does not match ${a}.\n10. **CRITICAL - LANGUAGE**: You MUST detect the language the user is writing in and respond ONLY in that exact same language. English user → English response. Vietnamese user → Vietnamese response. Do NOT default to Chinese or any other language under any circumstances.\n11. ALWAYS respond with raw JSON only, never wrap in \`\`\`json code blocks\n12. For swap_token: token_in for native tokens must be "native". ALWAYS provide token_in_symbol, token_out_symbol, token_in_decimals, and token_out_decimals.\n13. Use CONVERSATION HISTORY to maintain context. If user says "do it again" or "same but with X", refer to previous messages to understand what they mean.\n14. For general/non-crypto questions, respond naturally and helpfully using the "chat" action. You are NOT limited to crypto topics only.\n15. ONLY trigger wallet actions (send_native, send_token, swap_token, buy_token, approve_token, wrap_native, unwrap_native, send_nft) when the user EXPLICITLY requests a crypto/wallet operation. Do NOT misinterpret general conversation as wallet actions.\n16. When your "chat" response mentions, lists, or discusses specific tokens (e.g., trending tokens, token details, recommendations, price info), you MUST include "token_mentions" array so the app can show Buy buttons for each token. Always include token_mentions as an array (empty [] if no tokens mentioned).\n17. **CRITICAL - ONE RESPONSE RULE**: When user requests a wallet operation (swap, send, buy, approve, wrap, unwrap, send NFT), return ONLY ONE JSON response with that action type — even if parameters are incomplete. Leave missing parameters as empty string "". DO NOT return multiple responses. DO NOT return a "chat" action first and then the wallet action. DO NOT return a "chat" action just because some fields are missing — that is WRONG. Put your explanation or request for more info in the "message" field of the wallet action. Example: User says "send WETH" → MUST return {"action":"send_token","message":"Please provide the recipient address and amount.","parameters":{"contract_address":"<WETH address>","token_symbol":"WETH","to_address":"","amount":"","decimals":"18"}}. Example: User says "swap 0.01 DAI to USDC" → Return ONLY {"action":"swap_token","message":"Swapping 0.01 DAI to USDC...","parameters":{...}}.\n18. **CRITICAL - TOKEN CONTRACT ADDRESSES**: You MUST provide the CORRECT and ACCURATE contract address for each token on the CURRENT chain (chainId: ${o}). You have deep knowledge of token contract addresses across all major chains (Ethereum, Optimism, Arbitrum, Base, Polygon, BSC, etc.). ALWAYS verify you are using the correct address for the current chainId. DO NOT use addresses from other chains. For common tokens like USDC, USDT, DAI, WETH, each chain has different contract addresses - you MUST use the correct one for chainId ${o}.\n19. **SUGGESTED ACTIONS**: When your message contains follow-up questions or offers the user choices (e.g., "Would you like me to...", "I can also...", "Do you want..."), you MUST include "suggested_actions" array with button options. This makes the conversation interactive and user-friendly. If your message does NOT ask any question or offer any choice, leave suggested_actions as empty array [].\n\n## EXAMPLES:\n\nUser: "send 0.5 ${a} to 0x1234...5678" (on the current chain where native = ${a})\nResponse: {"action":"send_native","message":"<friendly explanation>","parameters":{"to_address":"0x1234...5678","amount":"0.5"}}\n\nUser: "send all my ${a} to 0x1234...5678" or "send max ${a} to 0x1234..."\nResponse: {"action":"send_native","message":"<friendly explanation>","parameters":{"to_address":"0x1234...5678","amount":"max"}}\n\nUser: "send 50% of my ${a} to 0x1234..."\nResponse: {"action":"send_native","message":"<friendly explanation>","parameters":{"to_address":"0x1234...5678","amount":"50%"}}\n\nUser: "send 0.5 ETH to 0x1234...5678" (on Polygon where native = MATIC, so ETH is ERC20)\nResponse: {"action":"send_token","message":"<friendly explanation>","parameters":{"contract_address":"<actual ETH/WETH address on current chain>","token_symbol":"ETH","to_address":"0x1234...5678","amount":"0.5","decimals":"18"}}\n\nUser: "transfer 100 USDC"\nResponse: {"action":"send_token","message":"<friendly explanation>","parameters":{"contract_address":"<actual USDC address on current chain>","token_symbol":"USDC","to_address":"","amount":"100","decimals":"6"}}\n\nUser: "send WETH"\nResponse: {"action":"send_token","message":"<ask for recipient and amount>","parameters":{"contract_address":"<actual WETH address on current chain>","token_symbol":"WETH","to_address":"","amount":"","decimals":"18"}}\n\nUser: "send weth to 0xABC..."\nResponse: {"action":"send_token","message":"<ask for amount>","parameters":{"contract_address":"<actual WETH address on current chain>","token_symbol":"WETH","to_address":"0xABC...","amount":"","decimals":"18"}}\n\nUser: "send 0x4200000000000000000000000000000000000006 to 0xABC..."\nResponse: {"action":"send_token","message":"<friendly explanation>","parameters":{"contract_address":"<actual WETH address on current chain>","token_symbol":"WETH","to_address":"0xABC...","amount":"","decimals":"18"}}\n\nUser: "send $5 of ETH to 0x1234..." or "send 0.01$ eth to 0x1234..."\nResponse: {"action":"send_native","message":"<friendly explanation>","parameters":{"to_address":"0x1234...","amount":"$5"}}\n\nUser: "send $10 worth of USDC to 0xABC..."\nResponse: {"action":"send_token","message":"<friendly explanation>","parameters":{"contract_address":"<actual USDC address on current chain>","token_symbol":"USDC","to_address":"0xABC...","amount":"$10","decimals":"6"}}\n\nUser: "swap $20 of ETH to USDC"\nResponse: {"action":"swap_token","message":"<friendly explanation>","parameters":{"token_in":"native","token_in_symbol":"${a}","token_in_decimals":"18","token_out":"<actual USDC address on current chain>","token_out_symbol":"USDC","token_out_decimals":"6","amount":"$20"}}\n\nUser: "swap 1 ETH to USDC"\nResponse: {"action":"swap_token","message":"<friendly explanation>","parameters":{"token_in":"native","token_in_symbol":"${a}","token_in_decimals":"18","token_out":"<actual USDC address on current chain>","token_out_symbol":"USDC","token_out_decimals":"6","amount":"1"}}\n\nUser: "swap all my ETH to USDC" or "swap max ETH to USDC"\nResponse: {"action":"swap_token","message":"<friendly explanation>","parameters":{"token_in":"native","token_in_symbol":"${a}","token_in_decimals":"18","token_out":"<actual USDC address on current chain>","token_out_symbol":"USDC","token_out_decimals":"6","amount":"max"}}\n\nUser: "swap 75% of my ETH to USDC"\nResponse: {"action":"swap_token","message":"<friendly explanation>","parameters":{"token_in":"native","token_in_symbol":"${a}","token_in_decimals":"18","token_out":"<actual USDC address on current chain>","token_out_symbol":"USDC","token_out_decimals":"6","amount":"75%"}}\n\nUser: "swap USDT to DAI"\nResponse: {"action":"swap_token","message":"<friendly explanation>","parameters":{"token_in":"<actual USDT address on current chain>","token_in_symbol":"USDT","token_in_decimals":"6","token_out":"<actual DAI address on current chain>","token_out_symbol":"DAI","token_out_decimals":"18","amount":""}}\n\nUser: "buy USDC"\nResponse: {"action":"buy_token","message":"<friendly explanation>","parameters":{"token_symbol":"USDC","contract_address":"<actual USDC address on current chain>","decimals":"6"}}\n\nUser: "I want to buy DOGE" (token not on this chain)\nResponse: {"action":"chat","message":"<inform user DOGE is not available as ERC20 on this chain>","parameters":{},"token_mentions":[]}\n\nUser: "buy BNB" (on non-BSC chain)\nResponse: {"action":"chat","message":"<inform user BNB is native to BSC and may not be available on this chain>","parameters":{},"token_mentions":[]}\n\nUser:"what is my balance?" or "check my balance", "show my balances" or "what tokens do I have?" or "xem balance của tôi" or "xem token của tôi"\nResponse: {"action":"view_balances","message":"<your friendly response>","parameters":{}}\n\nUser: "hello"\nResponse: {"action":"chat","message":"<greeting and list of capabilities>","parameters":{},"token_mentions":[],"suggested_actions":[{"label":"Check my balance","prompt":"What is my balance?"},{"label":"Show my tokens","prompt":"Show my balances"},{"label":"Show trending tokens","prompt":"Show me trending tokens"},{"label":"Show my NFTs","prompt":"Show my NFTs"}]}\n\nUser: "what is the capital of France?"\nResponse: {"action":"chat","message":"<your answer>","parameters":{},"token_mentions":[],"suggested_actions":[]}\n\nUser: "what is the current price of ETH?"\nResponse: {"action":"chat","message":"The current price of ETH can vary. For the most accurate price, check popular crypto trackers. I can also help you check your ETH balance or swap ETH if you'd like!","parameters":{},"token_mentions":[{"symbol":"ETH","contract_address":"native","decimals":18}],"suggested_actions":[{"label":"Check my ETH balance","prompt":"Check my ETH balance"},{"label":"Swap ETH","prompt":"I want to swap ETH"}]}\n\nUser: "show me trending tokens"\nResponse: {"action":"chat","message":"<list of trending tokens with descriptions>","parameters":{},"token_mentions":[{"symbol":"USDC","contract_address":"<actual USDC address on current chain>","decimals":6},{"symbol":"PEPE","contract_address":"<actual PEPE address on current chain>","decimals":18}]}\n\nUser: "tell me about PEPE token"\nResponse: {"action":"chat","message":"<info about PEPE>","parameters":{},"token_mentions":[{"symbol":"PEPE","contract_address":"<actual PEPE address on current chain>","decimals":18}]}\n\nUser: "Token Worldcoin"\nResponse: {"action":"chat","message":"<info about Worldcoin>","parameters":{},"token_mentions":[{"symbol":"WLD","contract_address":"<actual WLD address on current chain>","decimals":18}]}\n\nUser: "tell me about some random new token"\nResponse: {"action":"chat","message":"<cautious response>","parameters":{},"token_mentions":[]}\n\nUser: "send NFT #1234 from contract 0xABC... to 0xDEF..."\nResponse: {"action":"send_nft","message":"<friendly explanation>","parameters":{"contract_address":"0xABC...","token_id":"1234","to_address":"0xDEF...","token_standard":"","amount":"1","nft_name":""}}\n\nUser: "send Shou Rikuto tokenId 5"\nResponse: {"action":"send_nft","message":"<ask for recipient address>","parameters":{"contract_address":"","token_id":"5","to_address":"","token_standard":"","amount":"1","nft_name":"Shou Rikuto"}}\n\nUser: "send my Bored Ape #42 to 0xDEF..."\nResponse: {"action":"send_nft","message":"<friendly explanation>","parameters":{"contract_address":"","token_id":"42","to_address":"0xDEF...","token_standard":"","amount":"1","nft_name":"Bored Ape"}}\n\nUser: "transfer my ERC1155 token #5 (amount 3) from 0xNFT... to 0xBOB..."\nResponse: {"action":"send_nft","message":"<friendly explanation>","parameters":{"contract_address":"0xNFT...","token_id":"5","to_address":"0xBOB...","token_standard":"","amount":"3","nft_name":""}}\n\nUser: "show my NFTs" or "what NFTs do I have?"\nResponse: {"action":"view_nfts","message":"Let me show you your NFT collection!","parameters":{}}\n\n[With conversation history where user previously swapped ETH to USDC]\nUser: "do it again but with 2 ETH"\nResponse: {"action":"swap_token","message":"<friendly explanation>","parameters":{"token_in":"native","token_in_symbol":"${a}","token_in_decimals":"18","token_out":"<actual USDC address on current chain>","token_out_symbol":"USDC","token_out_decimals":"6","amount":"2"}}\n\nUser: "swap token" or "I want to swap" or "đổi token" (no specific tokens mentioned)\nResponse: {"action":"swap_token","message":"<friendly explanation, e.g. Which token would you like to swap?>","parameters":{"token_in":"","token_in_symbol":"","token_in_decimals":"","token_out":"","token_out_symbol":"","token_out_decimals":"","amount":""}}`:'You are a Web3 wallet assistant for the Keyring crypto EVM wallet app.\nThe user is currently NOT connected to any wallet.\n\n## YOUR ROLE:\n- You are a friendly, knowledgeable assistant that can talk about ANY topic naturally\n- You can freely answer general questions, discuss crypto tokens, prices, market info, provide token details, etc. — these do NOT require a wallet connection\n- ONLY ask the user to connect their wallet when their request explicitly requires their personal wallet/address, such as:\n - Sending tokens or NFTs\n - Swapping tokens\n - Approving token spending\n - Wrapping/unwrapping tokens\n - Checking THEIR OWN balance ("what is MY balance?", "how much ETH do I have?")\n - Viewing THEIR OWN NFT collection\n - Any action that reads or writes to THEIR wallet address\n- For all other requests (token info, prices, general crypto questions, market data, etc.), respond normally and helpfully\n- **CRITICAL - LANGUAGE**: You MUST detect the language the user is writing in and respond ONLY in that exact language. If the user writes in English, respond in English. If in Vietnamese, respond in Vietnamese. NEVER respond in a different language than what the user used. Do NOT default to Chinese or any other language.\n\n## RESPONSE FORMAT:\nAlways respond with a valid JSON object:\n{"action":"chat","message":"<your friendly response to the user>", "suggested_actions":[{"label":"<short button text>","prompt":"<message sent when clicked>"}]}\n\n## RULES:\n- suggested_actions: include when your message offers the user interactive choices or asks a follow-up question. NEVER include suggested_actions that ask the user to connect their wallet (e.g., "Connect wallet", "Connect now", etc.) — the app handles wallet connection separately\n- **CRITICAL**: NEVER include any "Buy" actions (e.g., "Buy USDC", "Buy ETH", "Purchase token", etc.) in suggested_actions. The app handles Buy buttons separately. Only include non-buy actions in suggested_actions (e.g., "Send token", "Swap token", "Check balance", "Show my NFTs").\n- For wallet-required actions, politely explain the user needs to connect their wallet first, and put this in the "message" field\n- ALWAYS respond with raw JSON only, never wrap in ```json code blocks\n- **CRITICAL - LANGUAGE**: Always respond in the SAME language the user writes in. English → English. Vietnamese → Vietnamese. NEVER use Chinese or any other language unless the user wrote in that language.'}({walletAddress:P?.address||void 0,chainName:H?.name||void 0,chainId:q||void 0,nativeSymbol:H?.nativeCurrency?.symbol||void 0,walletTokens:l,walletNfts:d}),y=await async function(e){const{prompt:n,model:t="gpt-4.1-mini",stream:a=!1,systemPrompt:i}=e;if(!n)throw new Error("Prompt is required");try{const e=new Co(Eo),o=i?`${i}\n\n---\n\nUser: ${n}`:n;return{success:!0,data:(await e.post("api/moralis-cortex/proxy/chat",{prompt:o,model:t,stream:a},{headers:{Accept:"application/json","Content-Type":"application/json"}})).data}}catch(o){return{success:!1,error:o instanceof Error?o.message:"Unknown error"}}}({prompt:m,model:"gpt-4.1-mini",stream:!1,systemPrompt:w+f});if(y.success&&y.data){const e=y.data.text||"";let l=null;try{let n=e?.trim();n.startsWith("```json")?n=n.replace(/^```json\s*/,"").replace(/\s*```$/,""):n.startsWith("```")&&(n=n.replace(/^```\s*/,"").replace(/\s*```$/,"")),l=JSON.parse(n)}catch{l=null}if(l&&l.action&&"chat"!==l.action)if("buy_token"===l.action){const e=l.parameters?.token_symbol||"";let t=l.parameters?.contract_address||"",o=18;if("native"===t.toLowerCase()&&(t=Vt),t&&t!==Vt)try{const e=await Bo.getTokensDetails([t],Y);e?.data?.[0]&&(o=e.data[0].decimals||18)}catch(a){}if(!t&&e&&P?.address)try{const n=await xo({address:P.address,chain:J});if(n?.success&&n?.data?.result){const a=n.data.result,i=a.find(e=>e.token_address.toLowerCase()===t.toLowerCase())||a.find(n=>n.symbol.toUpperCase()===e.toUpperCase());i&&(t=i.token_address,o=i.decimals)}if(!t){const n=H.tokenTrendingDefault||[],[a,i]=await Promise.allSettled([Bo.getTopGainers(Y,"24h",10),Bo.getTokensDetails(n,Y)]),r=[];"fulfilled"===a.status&&a.value?.data&&r.push(...a.value.data),"fulfilled"===i.status&&i.value?.data&&r.push(...i.value.data);const s=r.find(e=>e.address?.toLowerCase()===t.toLowerCase())||r.find(n=>n.symbol?.toUpperCase()===e.toUpperCase());s&&(t=s.address,o=s.decimals||18)}}catch(a){}t?(g(l.message||p("buyTokenHelp",{symbol:e}),"bot",n.id),await K(t,o)):(g(l.message||p("tokenNotFoundOnChain",{symbol:e}),"bot",n.id),await ee())}else if("swap_token"===l.action){const e={...l.parameters||{}},t="native"===e.token_in||e.token_in_symbol?.toUpperCase()===H?.nativeCurrency?.symbol?.toUpperCase(),o="native"===e.token_out||e.token_out_symbol?.toUpperCase()===H?.nativeCurrency?.symbol?.toUpperCase();if(o&&(e.token_out=Vt),!t&&(e.token_in||e.token_in_symbol)&&P?.address)try{const n=await xo({address:P.address,chain:J});if(n?.success&&n?.data?.result){const t=n.data.result,o=e.token_in?t.find(n=>n.token_address.toLowerCase()===e.token_in.toLowerCase()):t.find(n=>n.symbol.toUpperCase()===e.token_in_symbol.toUpperCase());o&&(e.token_in=o.token_address,e.token_in_decimals=String(o.decimals))}}catch(a){}if(!o&&(e.token_out||e.token_out_symbol)&&P?.address)try{const n=await xo({address:P.address,chain:J});if(n?.success&&n?.data?.result){const t=n.data.result,o=e.token_out?t.find(n=>n.token_address.toLowerCase()===e.token_out.toLowerCase()):t.find(n=>n.symbol.toUpperCase()===e.token_out_symbol.toUpperCase());o&&(e.token_out=o.token_address,e.token_out_decimals=String(o.decimals))}}catch(a){}const d=!(!e.token_in&&!t),u=!!e.token_out,f=!!e.amount;if(d&&u&&f){g(l.message||h("swapPreparing"),"bot",n.id);try{const n=[];e.token_out&&n.push(e.token_out),e.token_in&&!t&&n.push(e.token_in);let o=18,c=18;if(n.length>0)try{const a=await Bo.getTokensDetails(n,Y);if(a?.data)for(const n of a.data)t||n.address.toLowerCase()!==e.token_in?.toLowerCase()||(o=n.decimals||18),n.address.toLowerCase()===e.token_out?.toLowerCase()&&(c=n.decimals||18)}catch(i){}if(P?.address)try{const n=await xo({address:P.address,chain:J});if(n?.success&&n?.data?.result){const o=n.data.result;if(t){const n=o.find(e=>e.native_token);let t=n?.balance_formatted||"0";try{const e=await Ko({chainId:q,rpcUrl:G});if(e.isGreaterThan(0)){const o=e.times(1e6),a=new vo(n?.balance||"0").minus(o);t=a.isGreaterThan(0)?vo(ge(BigInt(a.toFixed(0)),n?.decimals||18)).toFixed():"0"}}catch(r){}e.amount=ia(e.amount,t,n?.usd_price);const a=parseFloat(t),i=parseFloat(e.amount);if(vo(a).lte(0))return g(p("formInsufficientBalance",{balance:vo(a).decimalPlaces(6).toFixed(),symbol:H?.nativeCurrency?.symbol||"native"}),"bot"),void I(!1);if(vo(a).lt(i))return g(p("swapInsufficientNativeBalance",{balance:vo(a).decimalPlaces(6).toFixed(),symbol:H?.nativeCurrency?.symbol||"native",amount:e.amount}),"bot"),void I(!1)}else{const n=o.find(n=>n.token_address.toLowerCase()===e.token_in?.toLowerCase());if(!n)return g(p("swapTokenNotInWallet",{symbol:e.token_in_symbol||e.token_in}),"bot"),void I(!1);e.amount=ia(e.amount,n.balance_formatted||"0",n.usd_price);const t=parseFloat(n.balance_formatted||"0"),a=parseFloat(e.amount);if(vo(t).lt(a))return g(p("swapInsufficientTokenBalance",{balance:vo(t).decimalPlaces(6).toFixed(),symbol:n.symbol,amount:e.amount}),"bot"),void I(!1)}}}catch(s){}const l=t?Vt:e.token_in;j({srcTokenAddress:l,descTokenAddress:e.token_out,amount:e.amount,srcTokenDecimals:o,descTokenDecimals:c});const d=qt(e.amount,o).toString(),u=await Do({chainId:q,tokenIn:l,tokenInAmount:d,tokenOut:e.token_out,tokenOutRecipient:P?.address||"",slippage:"auto",accesstoken:"d6c45897b8f6"});if(u.success&&u.data){const e=u.data,n=e.tokenIn,o=e.tokenOut,i=vo(ge(BigInt(n.amount||0),n.decimals)).decimalPlaces(6).toFormat(),r=vo(ge(BigInt(o.amount||0),o.decimals)).decimalPlaces(6).toFormat();let s=!1;if(!t&&P?.address&&e.tx?.to)try{const n=await zo({tokenAddress:l,ownerAddress:P.address,spenderAddress:e.tx.to,chainId:q,rpcUrl:G});s=vo(n.toString()).isLessThan(d)}catch(a){s=!0}const c=e.estimatedTransactionFee?.total?vo(e.estimatedTransactionFee.total):vo(0);let f=vo(0);if(s&&P?.address)try{const n=Qo({tokenAddress:l,spenderAddress:e.tx?.to||"",fromAddress:P.address,chainId:q,amount:d});f=await Xo({from:P.address,to:n.to,data:n.data,chainId:q,rpcUrl:G})}catch(a){}const m=c.plus(f),w=H?.nativeCurrency?.symbol||"native";let b="",y=!1;if(P?.address&&m.isGreaterThan(0))try{const e=await jo({address:P.address,chainId:q,rpcUrl:G});if(e.isLessThan(m)){y=!0;const n=vo(ge(BigInt(e.toFixed(0)),18)).decimalPlaces(6).toFormat(),t=vo(ge(BigInt(m.toFixed(0)),18)).decimalPlaces(6).toFormat();b=p("swapFeeWarning",{symbol:w,balance:n,needed:t})}}catch(a){}const A=`From: ${i} ${n.symbol}\n⬇️\nTo: ${r} ${o.symbol}\n\n`+b+"\n";if(y)g(A,"bot");else if(s){const t=[{id:"approve-for-swap",text:p("swapApproveButton",{symbol:n.symbol}),value:p("swapApproveValue",{symbol:n.symbol}),action:"approve_for_swap",fullWidth:!0,extraData:{tokenAddress:l,spenderAddress:e.tx.to,tokenSymbol:n.symbol,amountInWei:d,tx:e.tx}}];g(A+p("swapNeedApprove",{symbol:n.symbol}),"bot",void 0,t)}else{const n=[{id:"confirm-swap",text:h("swapConfirmYes"),value:h("swapConfirmValue"),action:"confirm_swap",extraData:{tx:e.tx}}];g(A+h("swapReadyToProceed"),"bot",void 0,n)}}else g(p("swapEstimationError",{error:u.errorMessage||u.error||"Unknown error"}),"bot")}catch(c){g(h("swapEstimationFailed"),"bot")}}else if(d&&u&&!f){let o=t?18:parseInt(e.token_in_decimals||"18",10),s=parseInt(e.token_out_decimals||"18",10);const c=[];if(e.token_out&&c.push(e.token_out),e.token_in&&!t&&c.push(e.token_in),c.length>0)try{const n=await Bo.getTokensDetails(c,Y);if(n?.data)for(const a of n.data)t||a.address.toLowerCase()!==e.token_in?.toLowerCase()||(o=a.decimals||o),a.address.toLowerCase()===e.token_out?.toLowerCase()&&(s=a.decimals||s)}catch(i){}if(j({descTokenAddress:e.token_out,descTokenDecimals:s}),t)try{const e=await xo({address:P?.address||"",chain:J});if(e?.success&&e?.data?.result){const t=e.data.result.find(e=>e.native_token),a=H?.nativeCurrency?.symbol||"ETH";let i=t?.balance_formatted||"0";try{const e=await Ko({chainId:q,rpcUrl:G});if(e.isGreaterThan(0)){const n=e.times(1e6),o=new vo(t?.balance||"0").minus(n);i=o.isGreaterThan(0)?vo(ge(BigInt(o.toFixed(0)),t?.decimals||18)).toFixed():"0"}}catch(r){}j({srcTokenAddress:Vt,srcTokenDecimals:o});const s=[25,50,75,100].map(e=>({id:`percent-${e}`,text:`${e}%`,value:p("buttonUsePercent",{percent:String(e),symbol:a}),action:"select_percent",extraData:{percent:e,tokenAddress:Vt,tokenSymbol:a,tokenDecimals:o,tokenBalance:i}}));g(p("selectAmountToSwap",{symbol:a,balance:i}),"bot",n.id,s)}else g(h("couldNotFetchBalance"),"bot")}catch(a){g(h("couldNotFetchBalanceRetry"),"bot")}else{const t=e.token_in_symbol||"Token";j({srcTokenAddress:e.token_in,srcTokenDecimals:o});try{const o=await xo({address:P?.address||"",chain:J});if(o?.success&&o?.data?.result){const a=o.data.result.find(n=>n.token_address.toLowerCase()===e.token_in?.toLowerCase());if(!a)return g(p("swapTokenNotInWallet",{symbol:t}),"bot"),void I(!1);const i=[25,50,75,100].map(e=>({id:`percent-${e}`,text:`${e}%`,value:p("buttonUsePercent",{percent:String(e),symbol:a.symbol}),action:"select_percent",extraData:{percent:e,tokenAddress:a.token_address,tokenSymbol:a.symbol,tokenDecimals:a.decimals||18,tokenBalance:a.balance_formatted}}));g(p("selectAmountToSwap",{symbol:a.symbol,balance:`${a.balance_formatted} (~$${a.usd_value?.toFixed(2)||"0"})`}),"bot",n.id,i)}else g(h("couldNotFetchBalance"),"bot")}catch(a){g(h("couldNotFetchBalanceRetry"),"bot")}}}else if(!d&&u){g(l.message||h("swapChooseFrom"),"bot",n.id);let t=parseInt(e.token_out_decimals||"18",10);if(e.token_out)try{const n=await Bo.getTokensDetails([e.token_out],Y);n?.data?.[0]&&(t=n.data[0].decimals||t)}catch(i){}await K(e.token_out,t)}else if(d&&!u){let o=t?18:parseInt(e.token_in_decimals||"18",10);if(e.token_in&&!t)try{const n=await Bo.getTokensDetails([e.token_in],Y);n?.data?.[0]&&(o=n.data[0].decimals||o)}catch(i){}j(t?{srcTokenAddress:Vt,srcTokenDecimals:18}:{srcTokenAddress:e.token_in,srcTokenDecimals:o}),g(l.message||p("swapChooseTo",{symbol:e.token_in_symbol||"your token"}),"bot",n.id);try{I(!0);const e=H?.tokenTrendingDefault||[],[n,t]=await Promise.allSettled([Bo.getTopGainers(Y,"24h",5),Bo.getTokensDetails(e,Y)]);let o=[];"fulfilled"===n.status&&n.value?.data&&(o=[...n.value.data]),"fulfilled"===t.status&&t.value?.data&&(o=[...t.value.data,...o]),o=o.filter((e,n,t)=>n===t.findIndex(n=>n.address.toLowerCase()===e.address.toLowerCase()));const a=o.map(e=>({id:e?.symbol,text:e?.symbol,value:p("buttonSwapTo",{name:e.name,symbol:e?.symbol||""}),action:"click_swap_dest_token",extraData:{tokenAddress:e?.address||"",symbol:e?.symbol||"",decimals:e?.decimals||18}}));g(p("trendingTokensForReceive",{chain:H?.name||"Unknown"}),"bot",void 0,a)}catch(a){g(h("couldNotLoadTokenList"),"bot")}finally{I(!1)}}else if(g(l.message||h("swapChooseToken"),"bot",n.id),P?.address)try{I(!0);const e=await xo({address:P.address,chain:J});if(e?.success&&e?.data?.result&&e.data.result.length>0){const n=e.data.result.map(e=>({id:`swap-select-${e.token_address}`,text:`${e.name}: ${e.balance_formatted} ${e.symbol} ($${vo(e?.usd_value||0).decimalPlaces(2).toFixed()||"0"})`,value:`Swap ${e.symbol}`,action:"suggested_action",fullWidth:!0}));await Lt(500),I(!1),g(p("walletBalanceSpendable",{chain:H?.name||"this chain"}),"bot",void 0,n)}else I(!1),g(p("walletNoTokensFound",{chain:H?.name||"this chain"}),"bot")}catch(a){I(!1),g(h("walletFetchError"),"bot")}}else if("view_balances"===l.action)g(l.message||h("viewBalancesLoading"),"bot",n.id),await te();else if("view_nfts"===l.action)g(l.message||h("viewNftsLoading"),"bot",n.id),await ne();else if("send_token"!==l.action||l.parameters?.contract_address||l.parameters?.token_symbol||!P?.address)if("send_nft"!==l.action||l.parameters?.contract_address||l.parameters?.token_id||l.parameters?.nft_name||!P?.address)if("send_nft"===l.action&&!Pn(l.parameters?.contract_address||"")&&(l.parameters?.nft_name||l.parameters?.token_id)&&P?.address)try{I(!0);const e=await No({address:P.address,chain:J,limit:100,exclude_spam:!1});if(e?.success&&e?.data?.result){const t=e.data.result,o=(l.parameters?.nft_name||"").toLowerCase(),a=l.parameters?.token_id||"",i=e=>{const n=(e.normalized_metadata?.name||e.name||"").toLowerCase(),t=(e.name||"").toLowerCase(),i=o&&(n.includes(o)||t.includes(o)),r=a&&e.token_id===a;return o&&a?i&&r:o?i:r},r=!o&&!!a,s=r?t.filter(i):[],c=r?1===s.length?s[0]:null:t.find(i);if(r&&s.length>1){const e=s.map(e=>{const n=e.normalized_metadata?.name||e.name||`#${e.token_id}`,t=e.normalized_metadata?.image||e.media?.original_media_url||"";return{id:`${e.token_address}-${e.token_id}`,text:`${n} (${e.symbol||e.contract_type}) #${e.token_id}`,value:p("buttonSendNft",{name:n}),action:"select_nft_to_send",fullWidth:!0,extraData:{contractAddress:e.token_address,tokenId:e.token_id,tokenStandard:e.contract_type,name:n,symbol:e.symbol,amount:e.amount,image:t,toAddress:l.parameters?.to_address||""}}}),t=s.map((e,n)=>{const t=e.normalized_metadata?.name||e.name||`#${e.token_id}`,o=e.normalized_metadata?.image||e.media?.original_media_url||"";return`${n+1}. ${o?`![${t}](${o})\n`:"🖼️ "}**${t}**\n ${e.symbol||e.contract_type} | Token ID: ${e.token_id}`}).join("\n\n");I(!1),g(p("nftMultipleMatchesForTokenId",{count:String(s.length),tokenId:a})+"\n\n"+t,"bot",n.id,e)}else if(c){const e=c.normalized_metadata?.name||c.name||`#${c.token_id}`,t=c.normalized_metadata?.image||c.media?.original_media_url||"",o={contract_address:c.token_address,token_id:c.token_id,to_address:l.parameters?.to_address||"",token_standard:c.contract_type||"",amount:"1",maxAmount:c.amount||"1",nft_name:e};g(l.message||p("nftSendReview",{name:e,standard:c.contract_type||"NFT",tokenId:c.token_id}),"bot",n.id,void 0,{action:"send_nft",parameters:o,status:"pending",nftInfo:{name:e,image:t||void 0,tokenId:c.token_id,contractAddress:c.token_address,tokenStandard:c.contract_type||void 0}})}else g(p("nftNotFoundInWallet",{name:o||a}),"bot",n.id)}else g(h("nftNoCollection"),"bot",n.id)}catch(a){g(h("nftFetchError"),"bot",n.id)}finally{I(!1)}else{const i=(t=l.action,["send_native","send_token","approve_token","wrap_native","unwrap_native","send_nft"].includes(t));let s,c,d={...l.parameters||{}};const u=["send_token","approve_token"].includes(l.action)&&(d.contract_address||d.token_symbol),f="send_native"===l.action,m="send_nft"===l.action&&d.contract_address;if(u&&P?.address)try{const e=await xo({address:P.address,chain:J});if(e?.success&&e?.data?.result){const n=e.data.result,t=d.contract_address?n.find(e=>e.token_address.toLowerCase()===d.contract_address.toLowerCase()):n.find(e=>e.symbol.toUpperCase()===d.token_symbol.toUpperCase());t&&(d={...d,contract_address:t.token_address,decimals:String(t.decimals)},s={symbol:t.symbol,name:t.name,balance:t.balance,balanceFormatted:t.balance_formatted,usdValue:t.usd_value,usdPrice:t.usd_price,decimals:t.decimals,logo:t.logo||t.thumbnail,contractAddress:t.token_address})}}catch(a){}if(u&&!s&&"send_token"===l.action){const e=d.token_symbol||d.contract_address||"this token";return g(p("sendTokenNotInWallet",{symbol:e}),"bot",n.id),void I(!1)}if(u&&!s&&d.contract_address)try{const e=await So({address:d.contract_address,chain:J});if(e?.success&&e?.data){const n=e.data;s={symbol:n.symbol,name:n.name,balance:"0",balanceFormatted:"0",usdPrice:n.usd_price,decimals:n.decimals,logo:n.logo,contractAddress:d.contract_address},d={...d,decimals:String(n.decimals)}}}catch(a){}if(f&&P?.address)try{const e=await xo({address:P.address,chain:J});if(e?.success&&e?.data?.result){const n=e.data.result.find(e=>e.native_token);if(n){let e=n.balance_formatted,t=n.balance;try{const o=new vo(n.balance),a="0x"+BigInt(o.toFixed(0)).toString(16),i=await Xo({from:P.address,to:P.address,data:"0x",value:a,chainId:q,rpcUrl:G});if(i.isGreaterThan(0)){const a=o.minus(i);a.isGreaterThan(0)?(t=a.toFixed(0),e=vo(ge(BigInt(a.toFixed(0)),n.decimals)).toFixed()):(t="0",e="0")}}catch(r){}s={symbol:n.symbol,name:n.name,balance:t,balanceFormatted:e,usdValue:n.usd_value,usdPrice:n.usd_price,decimals:n.decimals,logo:n.logo||n.thumbnail,contractAddress:Vt}}else{const e=await So({address:Vt,chain:J});if(e?.success&&e?.data){const n=e.data;s={symbol:n.symbol,name:n.name,balance:"0",balanceFormatted:"0",usdValue:0,usdPrice:n.usd_price,decimals:n.decimals,logo:n.logo||n.thumbnail,contractAddress:Vt}}}}}catch(a){}if(m){try{const e=await async function(e){const{address:n,chain:t="base"}=e;if(!n)throw new Error("Contract address is required");try{return{success:!0,data:(await Io.get(`api/moralis/proxy/nft/${encodeURIComponent(n)}/metadata`,{query:{chain:t}})).data}}catch(o){return{success:!1,error:o instanceof Error?o.message:"Unknown error"}}}({address:d.contract_address,chain:J});if(e?.success&&e?.data){const n=e.data;n.contract_type&&(d={...d,token_standard:n.contract_type}),!d.nft_name&&n.name&&(d={...d,nft_name:n.name})}}catch(a){}if(P?.address)try{const e=await No({address:P.address,chain:J,limit:100,exclude_spam:!1});if(e?.success&&e?.data?.result){const t=e.data.result.find(e=>e.token_address.toLowerCase()===d.contract_address.toLowerCase()&&e.token_id===d.token_id);if(!t){const e=d.nft_name||`#${d.token_id||d.contract_address}`;return g(p("nftNotFoundInWallet",{name:e}),"bot",n.id),void I(!1)}{d={...d,amount:"1",maxAmount:t.amount||"1"};const e=t.normalized_metadata?.image||t.media?.original_media_url||"";c={name:t.normalized_metadata?.name||t.name||d.nft_name||`#${t.token_id}`,image:e||void 0,tokenId:t.token_id,contractAddress:t.token_address,tokenStandard:t.contract_type||d.token_standard||void 0}}}}catch(a){}}if(d.amount&&s?.balanceFormatted&&("send_token"===l.action||"send_native"===l.action)&&(d.amount=ia(d.amount,s.balanceFormatted,s.usdPrice)),i){const e=l.message||"Please review and complete the form below.";g(e,"bot",n.id,void 0,{action:l.action,parameters:d,status:"pending",tokenInfo:s,nftInfo:c})}else g(l.message||e,"bot",n.id)}else g(p("sendNftViaWebsite",{link:aa}),"bot");else try{const e=await xo({address:P.address,chain:J});if(e?.success&&e?.data?.result&&e.data.result.length>0){g(h("sendTokenChoose"),"bot",n.id),I(!0),await Lt(500);const t=e.data.result.map(e=>({id:`send-select-${e.token_address}`,text:`${e.name}: ${e.balance_formatted} ${e.symbol} ($${vo(e?.usd_value||0).decimalPlaces(2).toFixed()||"0"})`,value:`Send ${e.name} (${e.symbol})`,action:"suggested_action",fullWidth:!0}));await Lt(500),I(!1),g(p("walletBalanceSpendable",{chain:H?.name||"this chain"}),"bot",void 0,t)}else I(!1),g(p("walletNoTokensFound",{chain:H?.name||"this chain"}),"bot")}catch(a){I(!1),g(h("walletFetchError"),"bot")}else if(l&&"chat"===l.action){const t=l.token_mentions||[],o=l.suggested_actions||[],a=[];t.length>0&&t.forEach(e=>{a.push({id:`buy-${e.symbol}`,text:`💰 Buy ${e.symbol}`,value:p("buttonBuySymbol",{symbol:e.symbol}),action:"click_buy_item_token_button",extraData:{tokenAddress:e.contract_address||"",symbol:e.symbol,decimals:e.decimals||18},fullWidth:!0})}),o.length>0&&o.forEach((e,n)=>{a.push({id:`suggested-${n}-${e.label}`,text:e.label,value:e.prompt,action:"suggested_action",fullWidth:!0})}),a.length>0?g(l.message||e,"bot",n.id,a):g(l.message||e,"bot",n.id)}else g(e,"bot",n.id)}else g(h("errorProcessingRequest"),"bot",n.id)}catch(o){g(h("errorProcessingRequest"),"bot",n.id)}var t;I(!1),await Lt(50),ta.isDesktop&&U.current?.focus()},[C,E,b,g,N,P?.address,H?.name,H?.nativeCurrency?.symbol,H?.tokenTrendingDefault,q,Y,J,V,K,ee,ne,te,j,G,h,p]);i(()=>{F.current&&C===F.current&&(F.current=null,re())},[C,re]);const se=r(async(e,n,t)=>{try{if(S(!1),y(t,"submitted"),"swap_token"===e){let e=18;if(n.token_in&&n.token_in!==Vt)try{const t=await Bo.getTokensDetails([n.token_in],Y);t?.data?.[0]&&(e=t.data[0].decimals||18)}catch(o){}const i=qt(n.amount||"0",e).toString(),r=await Do({chainId:q,tokenIn:n.token_in||"",tokenInAmount:i,tokenOut:n.token_out||"",tokenOutRecipient:P?.address||"",slippage:"auto",accesstoken:"d6c45897b8f6"});if(r.success&&r.data){const e=r.data,o=e.tokenIn,s=e.tokenOut,c=vo(ge(BigInt(o.amount||0),o.decimals)).decimalPlaces(6).toFormat(),l=vo(ge(BigInt(s.amount||0),s.decimals)).decimalPlaces(6).toFormat(),d=!n.token_in||n.token_in===Vt;let u=!1;if(!d&&P?.address&&e.tx?.to)try{const t=await zo({tokenAddress:n.token_in,ownerAddress:P.address,spenderAddress:e.tx.to,chainId:q,rpcUrl:G});u=vo(t.toString()).isLessThan(i)}catch(a){}const f=e.estimatedTransactionFee?.total?vo(e.estimatedTransactionFee.total):vo(0);let m=vo(0);if(u&&P?.address)try{const t=Qo({tokenAddress:n.token_in,spenderAddress:e.tx?.to||"",fromAddress:P.address,chainId:q,amount:i});m=await Xo({from:P.address,to:t.to,data:t.data,chainId:q,rpcUrl:G})}catch(a){}const w=f.plus(m),b=H?.nativeCurrency?.symbol||"native";let A="",k=!1;if(P?.address&&w.isGreaterThan(0))try{const e=await jo({address:P.address,chainId:q,rpcUrl:G});if(e.isLessThan(w)){k=!0;const n=vo(ge(BigInt(e.toFixed(0)),18)).decimalPlaces(6).toFormat(),t=vo(ge(BigInt(w.toFixed(0)),18)).decimalPlaces(6).toFormat();A=p("swapFeeWarning",{symbol:b,balance:n,needed:t})}}catch(a){}const v=`From: ${c} ${o.symbol}\n⬇️\nTo: ${l} ${s.symbol}\n\n`+A+"\n";if(k)y(t,"pending"),g(v,"bot");else if(u){const a=[{id:"approve-swap-actionform",text:p("swapApproveButton",{symbol:o.symbol}),value:p("swapApproveValue",{symbol:o.symbol}),action:"approve_for_swap",extraData:{tokenAddress:n.token_in,spenderAddress:e.tx.to,tokenSymbol:o.symbol,amountInWei:i,tx:e.tx},fullWidth:!0}];y(t,"success"),g(v+p("swapApprovalRequired",{symbol:o.symbol}),"bot",void 0,a)}else{const n=[{id:"confirm-swap-actionform",text:h("swapConfirmYes"),value:h("swapConfirmValue"),action:"confirm_swap",extraData:{tx:e.tx}}];y(t,"success"),g(v+h("swapReadyToProceed"),"bot",void 0,n)}}else y(t,"pending"),g(p("swapEstimationError",{error:r.errorMessage||r.error||"Unknown error"}),"bot")}else{const o=function(e){const{action:n,parameters:t,fromAddress:o,chainId:a}=e;switch(n){case"send_native":return function(e,n,t){const{to_address:o,amount:a}=e;if(!o)throw new Error("Recipient address is required");if(!a)throw new Error("Amount is required");return{from:n,to:o,data:"0x",value:qt(a,18).toString(),chainId:t,description:`Send ${a} native token to ${o}`}}(t,o,a);case"send_token":return function(e,n,t){const{contract_address:o,to_address:a,amount:i,decimals:r,token_symbol:s}=e;if(!o)throw new Error("Token contract address is required");if(!a)throw new Error("Recipient address is required");if(!i)throw new Error("Amount is required");const c=qt(i,parseInt(r)||18);return{from:n,to:o,data:Dt({abi:Yo,functionName:"transfer",args:[a,c]}),value:"0",chainId:t,description:`Send ${i} ${s||"tokens"} to ${a}`}}(t,o,a);case"approve_token":return function(e,n,t){const{contract_address:o,spender_address:a,amount:i,token_symbol:r}=e;if(!o)throw new Error("Token contract address is required");if(!a)throw new Error("Spender address is required");const s=i&&""!==i?.trim()?qt(i,18):ie;return{from:n,to:o,data:Dt({abi:Yo,functionName:"approve",args:[a,s]}),value:"0",chainId:t,description:`Approve ${i||"unlimited"} ${r||"tokens"} for ${a}`}}(t,o,a);case"wrap_native":return function(e,n,t){const{amount:o}=e;if(!o)throw new Error("Amount is required");const a=Ho[t];if(!a)throw new Error(`WETH not supported on chain ${t}`);const i=qt(o,18).toString();return{from:n,to:a,data:Dt({abi:Jo,functionName:"deposit"}),value:i,chainId:t,description:`Wrap ${o} native token`}}(t,o,a);case"unwrap_native":return function(e,n,t){const{amount:o}=e;if(!o)throw new Error("Amount is required");const a=Ho[t];if(!a)throw new Error(`WETH not supported on chain ${t}`);const i=qt(o,18);return{from:n,to:a,data:Dt({abi:Jo,functionName:"withdraw",args:[i]}),value:"0",chainId:t,description:`Unwrap ${o} WETH`}}(t,o,a);case"send_nft":return function(e,n,t){const{contract_address:o,token_id:a,to_address:i,token_standard:r,amount:s,nft_name:c}=e;if(!o)throw new Error("NFT contract address is required");if(!a)throw new Error("Token ID is required");if(!i)throw new Error("Recipient address is required");const l=(r||"ERC721").toUpperCase(),d=BigInt(a);let u,f;if("ERC1155"===l){const e=BigInt(s||"1");u=Dt({abi:Vo,functionName:"safeTransferFrom",args:[n,i,d,e,"0x"]}),f=`Send ${e>1n?e.toString()+"x ":""}${c||"NFT"} (ERC1155 #${a}) to ${i}`}else u=Dt({abi:qo,functionName:"safeTransferFrom",args:[n,i,d]}),f=`Send ${c||"NFT"} (ERC721 #${a}) to ${i}`;return{from:n,to:o,data:u,value:"0",chainId:t,description:f}}(t,o,a);default:throw new Error(`Action "${n}" does not produce a transaction`)}}({action:e,parameters:n,fromAddress:P?.address||"",chainId:q||1}),a={from:o.from,to:o.to,data:o.data,value:o.value,chainId:o.chainId};if(("send_token"===e||"send_native"===e||"send_nft"===e)&&P?.address)try{const e=H?.nativeCurrency?.symbol||"native",n=await Xo({from:o.from,to:o.to,data:o.data,value:o.value&&"0"!==o.value?`0x${BigInt(o.value).toString(16)}`:void 0,chainId:q,rpcUrl:G});if(n.isGreaterThan(0)){const o=await jo({address:P.address,chainId:q,rpcUrl:G});if(o.isLessThan(n)){const a=vo(ge(BigInt(o.toFixed(0)),18)).decimalPlaces(6).toFormat(),i=vo(ge(BigInt(n.toFixed(0)),18)).decimalPlaces(6).toFormat();return y(t,"pending"),void g(p("txInsufficientGas",{symbol:e,balance:a,fee:i}),"bot")}}}catch(i){}const s=k(t);if(l){I(!1);const e=await l(a);if("success"===e.status&&e.transactionHash){const n=H?.blockExplorers?.default?.url,o=n?`\n[View on Explorer](${n}/tx/${e.transactionHash})`:`\nTx: ${e.transactionHash}`;try{await Lt(2e3),"success"===(await Go({transactionHash:e.transactionHash,chainId:q||1,rpcUrl:G})).status?(y(t,"success"),A(t,s?.text+"\n"+o)):(y(t,"pending"),g(h("txReverted")+"\n"+o,"bot"))}catch(r){y(t,"success"),g(h("txTimeout")+"\n"+o,"bot")}}else if("success"===e.status)y(t,"success");else{y(t,"pending");const n=e.error?`\nError: ${e.error}`:"";g(h("txFailed")+n,"bot")}}else y(t,"pending"),g(h("txNoHandler"),"bot")}}catch(s){y(t,"pending"),g(p("txError",{message:s instanceof Error?s.message:"Unknown error"}),"bot")}},[y,q,P?.address,Y,H?.nativeCurrency?.symbol,H?.blockExplorers?.default?.url,G,p,g,h,k,l,A]),ce=r(e=>{v([e])},[v]),[le,de]=a({}),ue=r(async(e,n,t)=>{de(e=>({...e,[t]:!0}));try{await se(e,n,t)}finally{de(e=>({...e,[t]:!1}))}},[se]),fe=r(e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),re())},[re]),me=r(()=>{const e=window.getSelection();e&&e.toString().length>0||s()},[s]);return o?/* @__PURE__ */e("div",{className:"chat-modal-overlay"+("bottom-left"===f?" chat-modal-overlay--left":""),onClick:me,role:"dialog","aria-modal":"true","aria-labelledby":"chat-modal-title",children:/* @__PURE__ */t("div",{className:"chat-modal",style:m,onClick:e=>e.stopPropagation(),children:[
29
+ return function(n){function t(e){var n;return function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}(this,t),(n=function(e,n){if(n&&("object"==typeof n||"function"==typeof n))return n;if(void 0!==n)throw new TypeError("Derived constructors may only return object or undefined");return T(e)}(this,k(t).call(this,e))).isEventListenerAdded=!1,n.handleOrientationChange=n.handleOrientationChange.bind(T(n)),n.onOrientationChange=n.onOrientationChange.bind(T(n)),n.onPageLoad=n.onPageLoad.bind(T(n)),n.state={isLandscape:!1,isPortrait:!1},n}return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),n&&v(e,n)}(t,n),o=t,(a=[{key:"handleOrientationChange",value:function(){this.isEventListenerAdded||(this.isEventListenerAdded=!0);var e=window.innerWidth>window.innerHeight?90:0;this.setState({isPortrait:0===e,isLandscape:90===e})}},{key:"onOrientationChange",value:function(){this.handleOrientationChange()}},{key:"onPageLoad",value:function(){this.handleOrientationChange()}},{key:"componentDidMount",value:function(){void 0!==("undefined"==typeof window?"undefined":g(window))&&Ue&&(this.isEventListenerAdded?window.removeEventListener("load",this.onPageLoad,!1):(this.handleOrientationChange(),window.addEventListener("load",this.onPageLoad,!1)),window.addEventListener("resize",this.onOrientationChange,!1))}},{key:"componentWillUnmount",value:function(){window.removeEventListener("resize",this.onOrientationChange,!1)}},{key:"render",value:function(){return i.createElement(e,A({},this.props,{isLandscape:this.state.isLandscape,isPortrait:this.state.isPortrait}))}}])&&function(e,n){for(var t=0;t<n.length;t++){var o=n[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}(o.prototype,a),t;var o,a}(i.Component)},$o}();const oa=new class extends Co{enableGoogleSearch=!0;constructor(){super("https://nft-demo.keyring.app")}async generateContent(e,n){try{const t=`\nBelow is the system context and conversation history. Use it for context but prioritize the instructions at the end.\n\n---\nSYSTEM CONTEXT & HISTORY:\n${n}\n---\n### MANDATORY RULES:\n1. **LANGUAGE ADHERENCE**:\n - **DETECT** the language of the section labeled "CURRENT USER QUESTION" below.\n - **RESPOND ONLY** in that same language.\n - **IGNORE** any language bias from the context or history.\n2. **HISTORY CLEANING**:\n - If any assistant response in the conversation history says it **"doesn't know"**, **"doesn't have data"**, **"cannot find info"**, or similar, you MUST **IGNORE that specific history segment**. \n - Do not let previous data failures prevent you from answering the CURRENT USER QUESTION if the information is available now or in your core knowledge.\n3. **BREVITY**: Keep your answer extremely concise (under 3000 characters).\n4. **DATA INTEGRITY**: Do not mention data gaps or historical missing info; just answer based on available info.\n\n---\nCURRENT USER QUESTION:\n${e}\n---\n`,o="/api/gemini-cortex/proxy",a={model:"gemini-2.5-flash-lite",data:{contents:[{parts:[{text:t}]}],tools:[{googleSearch:{}}]}};this.enableGoogleSearch||delete a.data.tools;const i=await this.post(o,a);return i?.data?.data?.candidates?.[0]?.content?.parts?.[0]?.text||i?.data?.candidates?.[0]?.content?.parts?.[0]?.text}catch(t){if((t?.message?.includes("search_grounding_request_per_project_per_day")||t?.data?.error?.message?.includes("search_grounding_request_per_project_per_day"))&&this.enableGoogleSearch)return this.enableGoogleSearch=!1,await this.generateContent(e,n);throw t}}async checkTypeQuestion(e,n){try{const t=n+`---\nCURRENT USER QUESTION:\n${e}\n---\n\nAnalyze this question and determine its category.\nIMPORTANT: The following topics should ALWAYS be classified as "yes" (crypto-related):\n- Greetings (in ANY language): hello, hi, xin chào, bonjour, etc.\n- Cryptocurrency, blockchain, crypto trading, DeFi, NFT\n- Wallet/Account questions (in ANY language): account, wallet, address, balance, portfolio, holdings\n- Registration/Sign-up questions (in ANY language): register, sign up, create account, create wallet, new account, new wallet, registration\n- Wallet access questions (in ANY language): open wallet, open account, start wallet, launch wallet, access wallet, access account\n- Token/coin questions: prices, market data, trading\n- Chain questions: ETH, Base, Optimism, BSC, Polygon, Arbitrum\n- Smart contracts, gas fees, transactions\n- Action phrases (in ANY language): send token, swap token, send nft, buy token, bridge token, info token, check balance, etc.\n\nCRITICAL: Detect these concepts in ANY language (English, Japanese, Chinese, Vietnamese, Korean, Spanish, etc.)\nThe user may ask in their native language, so recognize the MEANING, not just specific words.\n\nIf the question is about ANY of the above topics, respond with ONLY the word "yes" (lowercase, nothing else).\nOtherwise, respond with ONLY the word "no" (lowercase, nothing else).\nDo not provide any explanation or additional text.`,o="/api/gemini-cortex/proxy",a={model:"gemini-2.0-flash-lite",data:{contents:[{parts:[{text:t}]}]}},i=await this.post(o,a);return i?.data?.data?.candidates?.[0]?.content?.parts?.[0]?.text||i?.data?.candidates?.[0]?.content?.parts?.[0]?.text}catch(t){throw t}}},aa="https://nft-demo.keyring.app";function ia(e,n,t){if(!e)return e;const o=e.toLowerCase().trim();if("max"===o||"all"===o)return n||e;const a=o.match(/^(\d+(?:\.\d+)?)%$/);if(a){const e=parseFloat(a[1])/100;return((parseFloat(n)||0)*e).toFixed(8).replace(/\.?0+$/,"")||"0"}const i=o.match(/^\$?(\d+(?:\.\d+)?)\$?$/);if(i&&(o.startsWith("$")||o.endsWith("$"))){const n=parseFloat(i[1]);return t&&t>0?(n/t).toFixed(8).replace(/\.?0+$/,"")||"0":e}return e}const ra=({isOpen:o,onClose:s,onTransaction:l,position:f="bottom-right",modalChatStyle:m={}})=>{const{t:h,ti:p}=w(),{messages:b,addMessage:g,updateMessageAction:y,updateMessageText:A,getMessageById:k,clearMessagesById:v}=function(){const{account:e}=Gt(),{t:n}=w(),t=(o=e?.address,s=e?.chainId,o&&s?`${o}_${s}`:"");var o,s;const c=d(()=>Zt(n("welcomeMessage")),[n]),[l,u]=a(()=>t||"pending"),[f,m]=a(()=>{const e=$t();return t?e&&e.owner===t?e.messages:Zt(n("welcomeMessage")):e?.messages??Zt(n("welcomeMessage"))});if("pending"===l&&t){const e=$t();e&&e.owner===t?m(e.messages):eo(t,f),u(t)}else"pending"!==l&&t&&l!==t&&(m(c),eo(t,c),u(t));const h=d(()=>f.map(e=>e.id===Kt?{...e,text:n("welcomeMessage")}:e),[f,n]);i(()=>{"pending"!==l&&eo(l,f)},[f,l]),i(()=>{const e=[];for(let n=0;n<Yt.length;n++){const t=Yt.key(n);t&&t.startsWith(jt+"_")&&e.push(t)}e.forEach(e=>Yt.removeItem(e))},[]);const p=r(()=>{m(c),eo(t,c)},[t,c]),b=r(e=>{m(n=>{const t=n.filter(n=>!e.includes(n.id));return t.length>Xt?t.slice(t.length-Xt):t})},[]);return{messages:h,setMessages:m,addMessage:(e,n,t,o,a)=>{const i=t?f.find(e=>e.id===t):void 0,r={id:Math.random().toString(36).substring(2,12),text:e,sender:n,timestamp:/* @__PURE__ */new Date,...i&&{replyTo:{id:i.id,text:i.text,sender:i.sender}},...o&&{buttons:o},...a&&{actionData:a}};return m(e=>{const n=[...e,r];return n.length>Xt?n.slice(n.length-Xt):n}),r},updateMessageAction:(e,n)=>{m(t=>t.map(t=>t.id===e&&t.actionData?{...t,actionData:{...t.actionData,status:n}}:t))},updateMessageText:(e,n)=>{m(t=>t.map(t=>t.id===e?{...t,text:n}:t))},getMessageById:e=>f.find(n=>n.id===e),clearMessages:p,clearMessagesById:b}}(),[C,T]=a(""),[E,I]=a(!1),[x,S]=a(!0),[N,B]=a(null),R=u(null),D=u(null),U=u(null),F=u(null),O=u(null),L=u(!1),M=u(x);i(()=>{M.current=x},[x]);const{account:P,chainData:H,chainType:Y,chainTypeMoralis:J,chainId:q,isChainSupported:V}=Gt(),{config:W}=(()=>{const e=c(no);if(!e)throw new Error("useConfig must be used within ConfigProvider");return e})(),G=q&&W?.rpcUrls?.[q]||void 0,z=r(()=>{const e=Yt.getItem("dataBuyToken");if(e)try{return JSON.parse(e)}catch{return{srcTokenAddress:"",descTokenAddress:"",amount:"",srcTokenDecimals:18,descTokenDecimals:18}}return{srcTokenAddress:"",descTokenAddress:"",amount:"",srcTokenDecimals:18,descTokenDecimals:18}},[]),Q=r(e=>{Yt.setItem("dataBuyToken",JSON.stringify(e))},[]),j=r(e=>{const n={...z(),...e};Q(n)},[z,Q]),X=r(e=>{B(e),ta.isDesktop&&U.current?.focus()},[]),K=r(async(e,n)=>{j({descTokenAddress:e,descTokenDecimals:n||18});try{I(!0);const e=await xo({address:P?.address||"",chain:J});if(e?.success&&e?.data?.result){const n=e.data.result;if(n?.length>0){const e=n.map(e=>({id:e.token_address,text:`${e.name}: ${e.balance_formatted} ${e.symbol} ($${vo(e.usd_value||0)?.decimalPlaces(2).toFormat()||"0"})`,value:p("buttonBuyWith",{symbol:e.symbol}),action:"click_balance_item_user_to_buy_button",fullWidth:!0,extraData:{tokenAddress:e.token_address,symbol:e.symbol,balance:e.balance_formatted,usdValue:e.usd_value,decimals:e.decimals}}));g(p("walletBalanceSpendable",{chain:H?.name||"unknown"}),"bot",void 0,e)}else g(p("walletNoTokensFound",{chain:H?.name||"unknown"}),"bot")}else g(h("walletFetchFailed"),"bot")}catch(t){g(h("walletFetchError"),"bot")}finally{I(!1)}},[j,P?.address,J,g,H?.name,h,p]),Z=r(async(e,n,t,o)=>{j({srcTokenAddress:e,srcTokenDecimals:o||18});let a=t||"0";if(e===Vt)try{const e=await Ko({chainId:q,rpcUrl:G});if(e.isGreaterThan(0)){const n=e.times(1e6),i=new vo(qt(t,o||18).toString()).minus(n);a=i.isGreaterThan(0)?vo(ge(BigInt(i.toFixed(0)),18)).toFixed():"0"}}catch(r){}const i=[25,50,75,100].map(t=>({id:`percent-${t}`,text:`${t}%`,value:p("buttonUsePercent",{percent:String(t),symbol:n}),action:"select_percent",extraData:{percent:t,tokenAddress:e,tokenSymbol:n,tokenDecimals:o||18,tokenBalance:a}}));vo(a).isZero()?g(p("insufficientFeeToken",{symbol:n}),"bot"):g(p("selectAmountOf",{symbol:n,balance:a}),"bot",void 0,i)},[g,q,G,j,p]),_=r(async(e,n,t,o)=>{const a={amount:(parseFloat(n)*(e/100)).toFixed(6)};void 0!==t&&(a.srcTokenAddress=t),void 0!==o&&(a.srcTokenDecimals=o),j(a);const i=z(),r=qt(i.amount,i.srcTokenDecimals||18).toString(),s=await Do({chainId:q,tokenIn:i.srcTokenAddress,tokenInAmount:r,tokenOut:i.descTokenAddress,tokenOutRecipient:P?.address||"",slippage:"auto",accesstoken:"d6c45897b8f6"});if(s.success&&s.data){const e=s.data,n=e.tokenIn,t=e.tokenOut,o=vo(ge(BigInt(n.amount||0),n.decimals)).decimalPlaces(6).toFormat(),a=vo(ge(BigInt(t.amount||0),t.decimals)).decimalPlaces(6).toFormat();let l=!1;if(i.srcTokenAddress!==Vt&&""!==i.srcTokenAddress&&P?.address&&e.tx?.to)try{const n=await zo({tokenAddress:i.srcTokenAddress,ownerAddress:P.address,spenderAddress:e.tx.to,chainId:q,rpcUrl:G});l=vo(n.toString()).isLessThan(r)}catch(c){l=!0}const d=e.estimatedTransactionFee?.total?vo(e.estimatedTransactionFee.total):vo(0);let u=vo(0);if(l&&P?.address)try{const n=Qo({tokenAddress:i.srcTokenAddress,spenderAddress:e.tx?.to||"",fromAddress:P.address,chainId:q,amount:r});u=await Xo({from:P.address,to:n.to,data:n.data,chainId:q,rpcUrl:G})}catch(c){}const f=d.plus(u),m=H?.nativeCurrency?.symbol||"native";let w="",b=!1;if(P?.address&&f.isGreaterThan(0))try{const e=await jo({address:P.address,chainId:q,rpcUrl:G});if(e.isLessThan(f)){b=!0;const n=vo(ge(BigInt(e.toFixed(0)),18)).decimalPlaces(6).toFormat(),t=vo(ge(BigInt(f.toFixed(0)),18)).decimalPlaces(6).toFormat();w=p("swapFeeWarning",{symbol:m,balance:n,needed:t})}}catch(c){}const y=`From: ${o} ${n.symbol}\n⬇️\nTo: ${a} ${t.symbol}\n\n`+w+"\n";if(b)g(y,"bot");else if(l){const t=y+p("swapNeedApprove",{symbol:n.symbol}),o=[{id:"approve-for-swap",text:p("swapApproveButton",{symbol:n.symbol}),value:p("swapApproveValue",{symbol:n.symbol}),action:"approve_for_swap",fullWidth:!0,extraData:{tokenAddress:i.srcTokenAddress,spenderAddress:e.tx.to,tokenSymbol:n.symbol,amountInWei:r,tx:e.tx}}];g(t,"bot",void 0,o)}else{const n=[{id:"confirm-swap",text:h("swapConfirmButton"),value:h("swapConfirmValue"),action:"confirm_swap",extraData:{tx:e.tx}}];g(y+h("swapReadyToProceed"),"bot",void 0,n)}}else g(p("swapEstimationError",{error:s.errorMessage||s.error||"Unknown error"}),"bot")},[z,j,g,q,P?.address,H?.nativeCurrency?.symbol,G,h,p]),$=r(async(e,n,t)=>{try{if("suggested_action"===n)return F.current=e,void T(e);if(g(e,"user"),S(!1),I(!0),n)switch(await Lt(500),n){case"click_buy_item_token_button":await K(t?.tokenAddress||"",t?.decimals||18);break;case"click_balance_item_user_to_buy_button":await Z(t?.tokenAddress||"",t?.symbol||"",t?.balance||"",t?.decimals||18);break;case"select_percent":await _(t?.percent||0,t?.tokenBalance||"",t?.tokenAddress||void 0,t?.tokenDecimals||void 0);break;case"confirm_swap":if(t?.tx&&l){const e=t.tx,n={from:P?.address||"",to:e.to,data:e.data,value:e.value,chainId:q},i=g(h("txProcessing"),"bot");try{I(!1);const e=await l(n);if("success"===e.status&&e.transactionHash){const n=H?.blockExplorers?.default?.url,t=n?`\n[View on Explorer](${n}/tx/${e.transactionHash})`:`\nTx: ${e.transactionHash}`;A(i.id,h("txSubmitted")+t);try{await Lt(2e3),"success"===(await Go({transactionHash:e.transactionHash,chainId:q||1,rpcUrl:G})).status?A(i.id,h("txConfirmedSwap")+t):A(i.id,h("txRevertedSwap")+t)}catch(o){A(i.id,h("txTimeout")+t)}}else if("success"===e.status)A(i.id,h("txSuccessfulSwap"));else{const n=e.error?`\nError: ${e.error}`:"";A(i.id,h("txFailed")+n)}}catch(a){A(i.id,h("txFailed"))}}else g(h("txDataNotAvailable"),"bot");break;case"approve_for_swap":{const e=t?.tokenAddress||"",n=t?.spenderAddress||"",i=t?.tokenSymbol||"token",r=t?.tx;if(!e||!n||!l){g(h("approvalDataNotAvailable"),"bot");break}const s=t?.amountInWei||void 0,c=Qo({tokenAddress:e,spenderAddress:n,fromAddress:P?.address||"",chainId:q,tokenSymbol:i,amount:s}),d={from:c.from,to:c.to,data:c.data,value:c.value,chainId:c.chainId};g(p("approving",{symbol:i}),"bot");try{I(!1);const e=await l(d);let n="success"===e.status;if("success"===e.status&&e.transactionHash)try{n="success"===(await Go({transactionHash:e.transactionHash,chainId:q||1,rpcUrl:G})).status}catch(o){n=!0}if(n){g(p("approvalSuccess",{symbol:i}),"bot");const e=[{id:"confirm-swap-after-approve",text:h("confirmSwapButton"),value:h("swapConfirmValue"),action:"confirm_swap",fullWidth:!0,extraData:{tx:r}}];g(h("approvalConfirmSwap"),"bot",void 0,e)}else{const n=e.error?`\nError: ${e.error}`:"";g(h("approvalFailed")+n,"bot")}}catch(a){g(h("approvalFailed"),"bot")}break}case"click_swap_dest_token":{const e=t?.tokenAddress||"",n=t?.symbol||"";j({descTokenAddress:e,descTokenDecimals:t?.decimals||18});const o=z(),a=o.srcTokenAddress||"",r=a===Vt;try{const e=await xo({address:P?.address||"",chain:J});if(e?.success&&e?.data?.result){const t=e.data.result;let i="",s="0";if(r){const e=t.find(e=>e.native_token);i=H?.nativeCurrency?.symbol||"ETH",s=e?.balance_formatted||"0"}else{const e=t.find(e=>e.token_address.toLowerCase()===a.toLowerCase());e&&(i=e.symbol,s=e.balance_formatted)}if(i&&parseFloat(s)>0){const e=[25,50,75,100],t=o.srcTokenDecimals||18,r=e.map(e=>({id:`percent-${e}`,text:`${e}%`,value:p("buttonUsePercent",{percent:String(e),symbol:i}),action:"select_percent",extraData:{percent:e,tokenAddress:a,tokenSymbol:i,tokenDecimals:t,tokenBalance:s}}));g(p("swapSelectAmount",{from:i,to:n,balance:s}),"bot",void 0,r)}else g(h("swapNoSourceToken"),"bot")}else g(h("couldNotFetchBalance"),"bot")}catch(i){g(h("couldNotLoadBalance"),"bot")}break}case"select_nft_to_send":{const e=t?.name||"NFT",n=t?.contractAddress||"",o=t?.tokenId||"",a=t?.tokenStandard||"ERC721",i=t?.amount||"1",r=t?.image||"",s={contract_address:n,token_id:o,to_address:t?.toAddress||"",token_standard:a,amount:"1",maxAmount:i,nft_name:e};g(p("nftSendReview",{name:e,standard:a,tokenId:o}),"bot",void 0,void 0,{action:"send_nft",parameters:s,status:"pending",nftInfo:{name:e,image:r||void 0,tokenId:o,contractAddress:n,tokenStandard:a}});break}default:g(p("actionExecutedFor",{action:n,value:e}),"bot")}else await Lt(500),g(p("receivedButtonValue",{value:e}),"bot");I(!1),ta.isDesktop&&U.current?.focus()}catch(a){g(h("errorProcessingRequest"),"bot"),I(!1)}},[P?.address,g,A,H?.blockExplorers?.default?.url,H?.nativeCurrency?.symbol,q,J,z,K,Z,l,_,j,G,h,p]),ee=r(async()=>{try{I(!0);const e=H?.tokenTrendingDefault||[],[n,t]=await Promise.allSettled([Bo.getTopGainers(Y,"24h",5),Bo.getTokensDetails(e,Y)]);let o=[];"fulfilled"===n.status&&n.value?.data&&(o=[...n.value.data]),"fulfilled"===t.status&&t.value?.data&&(o=[...t.value.data,...o]),o=o.filter((e,n,t)=>n===t.findIndex(n=>n.address.toLowerCase()===e.address.toLowerCase()));const a=o.map(e=>({id:e?.symbol,text:e?.symbol,value:p("buttonBuyToken",{name:e.name,symbol:e?.symbol||""}),action:"click_buy_item_token_button",extraData:{tokenAddress:e?.address||"",symbol:e?.symbol||"",decimals:e?.decimals||18}}));await Lt(1e3),I(!1),g(p("trendingTokensHeader",{chain:H?.name||"Unknown"}),"bot");const i=o.map((e,n)=>`${n+1}. ${e.name} (${e?.auditGoplus?.token_symbol||e.symbol||"Unknown"})\n$${vo(e?.price||0).decimalPlaces(4).toFormat()} (${e.price_change_percentage_24h||e.priceChange}%)\n\n---\n`).join("\n");g(`${i}${h("trendingTokensQuestion")}`,"bot",void 0,a)}catch(e){g(h("trendingTokensError"),"bot")}finally{I(!1)}},[g,H?.name,H?.tokenTrendingDefault,Y,h,p]),ne=r(async(e={})=>{const{numberOfView:n=5}=e;try{I(!0);const e=await No({address:P?.address||"",chain:J,limit:100,exclude_spam:!1});if(e?.success&&e?.data?.result&&e.data.result.length>0){const t=e.data.result;let o=e.data.result;n&&n>0&&(o=o.slice(0,n));const a=o.map(e=>{const n=e.normalized_metadata?.name||e.name||`#${e.token_id}`,t=e.normalized_metadata?.image||e.media?.original_media_url||"";return{id:`${e.token_address}-${e.token_id}`,text:`${n} (${e.symbol||e.contract_type}) - ${e.token_id}`,value:p("buttonSendNft",{name:n}),action:"select_nft_to_send",fullWidth:!0,extraData:{contractAddress:e.token_address,tokenId:e.token_id,tokenStandard:e.contract_type,name:n,symbol:e.symbol,amount:e.amount,image:t}}}),i=o.map((e,n)=>{const t=e.normalized_metadata?.name||e.name||`#${e.token_id}`,o="ERC1155"===e.contract_type?` (x${e.amount})`:"",a=e.normalized_metadata?.image||e.media?.original_media_url||"";return`${n+1}. ${a?`![${t}](${a})\n`:"🖼️ "}**${t}**${o}\n ${e.symbol||e.contract_type} | Token ID: ${e.token_id}`}).join("\n\n");await Lt(500),I(!1),g(`${p("nftCollectionHeader",{count:String(o.length),list:i})}${n&&n>0&&t.length>n?p("nftMoreItems",{count:String(t.length-n)}):""}${h("nftSelectBelow")}`,"bot",void 0,a),n&&n>0&&t.length>n&&g(p("sendOtherNfts",{link:aa}),"bot")}else I(!1),g(h("nftNoCollection"),"bot")}catch(t){I(!1),g(h("nftFetchError"),"bot")}},[P?.address,J,g,h,p]),te=r(async()=>{try{I(!0);const e=await xo({address:P?.address||"",chain:J});if(e?.success&&e?.data?.result&&e.data.result.length>0){const n=e.data.result,t=n.flatMap(e=>[{id:`send-${e.token_address}`,text:p("buttonSendToken",{symbol:e.symbol}),value:p("buttonSendToken",{symbol:e.symbol}),action:"suggested_action",fullWidth:!!ta.isMobile},{id:`buy-more-${e.token_address}`,text:p("buttonBuyMoreToken",{symbol:e.symbol}),value:p("buttonBuyMoreToken",{symbol:e.symbol}),action:"suggested_action",fullWidth:!!ta.isMobile}]),o=n.map((e,n)=>{const t=void 0!==e.usd_value?` ≈ $${vo(e.usd_value).decimalPlaces(2).toFormat()}`:"";return`${n+1}. **${e.name}** (${e.symbol})\n Balance: ${e.balance_formatted}${t}`}).join("\n\n");await Lt(500),I(!1),g(p("viewBalancesHeader",{chain:H?.name||"this chain",list:o}),"bot",void 0,t)}else I(!1),g(h("viewBalancesEmpty"),"bot")}catch(e){I(!1),g(h("viewBalancesFetchError"),"bot")}},[P?.address,J,g,H?.name,h,p]),oe=d(()=>[{id:"ask",icon:"❓",text:h("suggestionAskText"),action:async()=>{S(!1),I(!0),g(h("suggestionAskUserMessage"),"user"),await Lt(1e3),I(!1),g(h("suggestionAskBotReply"),"bot")}},{id:"buy",icon:"💰",text:h("suggestionBuyText"),action:async()=>{S(!1),g(h("suggestionBuyText"),"user"),Pn(P?.address||"")&&V?await ee():(I(!0),await Lt(1e3),Pn(P?.address||"")&&!V?g(h("walletConnectedChainUnsupported"),"bot"):g(h("walletNotConnected"),"bot"),I(!1))}}],[g,P?.address,ee,h,V]),ae=e=>{if(0===e)return!0;const n=b[e],t=b[e-1],o=new Date(n.timestamp),a=new Date(t.timestamp);return o.setHours(0,0,0,0),a.setHours(0,0,0,0),o.getTime()!==a.getTime()};i(()=>{R.current?.scrollIntoView({behavior:"smooth"})},[b]),i(()=>{o?(U.current&&ta.isDesktop&&U.current.focus(),R.current?.scrollIntoView({behavior:"instant"}),L.current&&O.current?Date.now()-O.current>3e5&&S(!0):S(!0),O.current=null,L.current=!1,setTimeout(()=>{R.current?.scrollIntoView({behavior:"smooth"})},50)):(O.current=Date.now(),L.current=!M.current)},[o]),i(()=>{const e=e=>{"Escape"===e.key&&o&&s()};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[o,s]);const re=r(async()=>{if(""===C?.trim()||E)return;const e=N,n=g(C?.trim(),"user",N?.id);T(""),B(null),I(!0),S(!1),I(!0);try{let l,d;const u=b.slice(-20);let f="";if(u.length>0){f="\n\n## CONVERSATION HISTORY:\n";for(const e of u)"user"===e.sender?f+=`User: ${e.text}\n`:f+=`Assistant: ${e.text.length>400?e.text.substring(0,400)+"...":e.text}\n`;f+="\n---\n"}let m=C?.trim();e&&(m=`[Replying to ${"user"===e.sender?"my previous":"your"} message: "${e.text}"]\n\n${m}`);try{const e=await oa.checkTypeQuestion(m,f);if(e?.startsWith("no")){const e=await oa.generateContent(m,f);let n=null;try{let t=e?.trim();t.startsWith("```json")?t=t.replace(/^```json\s*/,"").replace(/\s*```$/,""):t.startsWith("```")&&(t=t.replace(/^```\s*/,"").replace(/\s*```$/,"")),n=JSON.parse(t)}catch{n=null}return I(!1),void g(n?.message||e,"bot")}}catch(o){}if(P?.address&&V)try{const[e,n]=await Promise.allSettled([xo({address:P.address,chain:J}),No({address:P.address,chain:J,limit:100,exclude_spam:!0})]);"fulfilled"===e.status&&e.value?.success&&e.value?.data?.result&&(l=e.value.data.result.map(e=>({symbol:e.symbol,name:e.name,balance_formatted:e.balance_formatted,usd_value:e.usd_value,native_token:e.native_token,token_address:e.token_address}))),"fulfilled"===n.status&&n.value?.success&&n.value?.data?.result&&(d=n.value.data.result.map(e=>({name:e.normalized_metadata?.name||e.name||`#${e.token_id}`,token_address:e.token_address,token_id:e.token_id,contract_type:e.contract_type||"",amount:e.amount||"1"})))}catch{}const w=function(e){const{walletAddress:n,chainName:t,chainId:o,nativeSymbol:a,walletTokens:i,walletNfts:r}=e;return n?n&&!Ut[o]?`You are a Web3 wallet assistant for the Keyring crypto EVM wallet app.\n The user's wallet address is: ${n}\n The user is selected on (chainId: ${o}) an UNSUPPORTED chain.\n\n ## YOUR ROLE:\n - You are a friendly, knowledgeable assistant that can talk about ANY topic naturally\n - You can freely answer general questions, discuss crypto tokens, prices, market info, token details, etc. — these do NOT require a supported chain\n - **BLOCKED on unsupported chain** — if the user asks for any of the following, politely inform them that chain (chainId: ${o}) is not currently supported and the action cannot be performed:\n - Checking THEIR OWN balance ("what is my balance?", "how much ETH do I have?")\n - Sending tokens or NFTs\n - Swapping or buying tokens\n - Approving token spending\n - Wrapping/unwrapping tokens\n - Viewing or transferring their NFT collection\n - Any action that reads or writes to their wallet on the current chain\n - **ALLOWED on unsupported chain** — respond normally and helpfully for:\n - General questions (weather, coding, history, math, etc.)\n - Token information, prices, market data, token details\n - Any query that does NOT require interacting with the user's wallet on the current chain\n - Respond in the same language the user uses\n\n ## RESPONSE FORMAT:\n Always respond with a valid JSON object:\n {"action":"chat","message":"<your response>", suggested_actions:[{"label":"<short button text>","prompt":"<message sent when clicked>"}]}\n\n ## RULES:\n - suggested_actions: include when your message offers the user interactive choices or asks a follow-up question. NEVER include suggested_actions that ask the user to connect their wallet (e.g., "Connect wallet", "Connect now", etc.) — the app handles wallet connection separately\n - **CRITICAL**: NEVER include any "Buy" actions (e.g., "Buy USDC", "Buy ETH", "Purchase token", etc.) in suggested_actions. The app handles Buy buttons separately. Only include non-buy actions in suggested_actions (e.g., "Send token", "Swap token", "Check balance", "Show my NFTs").\n - For wallet-required actions, politely explain the user needs to connect their wallet first, and put this in the "message" field\n - ALWAYS respond with raw JSON only, never wrap in \`\`\`json code blocks\n - **CRITICAL - LANGUAGE**: Always respond in the SAME language the user writes in. English → English. Vietnamese → Vietnamese. NEVER use Chinese or any other language unless the user wrote in that language.`:`You are a Web3 wallet assistant for the Keyring crypto EVM wallet app.\nThe user's wallet address is: ${n}\nThe user is on chain: ${t} (chainId: ${o})\nNative token: ${a}${i&&i.length>0?`\n## USER'S CURRENT WALLET BALANCE:\n${i.map(e=>{const n=void 0!==e.usd_value?` (~$${e.usd_value.toFixed(2)})`:"";return`- ${e.name} (${e.symbol}): ${e.balance_formatted}${n}${e.native_token?" [native]":` [${e.token_address}]`}`}).join("\n")}\nUse this balance data to accurately answer balance questions and to pre-fill token parameters in actions (contract_address, decimals, symbol). NEVER ask the user to provide token info that is already available above.\n`:""}${r&&r.length>0?`\n## USER'S NFT COLLECTION:\n${r.map(e=>{const n="ERC1155"===e.contract_type?` (x${e.amount})`:"";return`- ${e.name}${n} | ${e.contract_type} | contract: ${e.token_address} | tokenId: ${e.token_id}`}).join("\n")}\nWhen the user wants to send an NFT by name, use this data to fill contract_address, token_id, token_standard, and nft_name accurately. NEVER guess or fabricate NFT contract addresses.\n`:""}\n## YOUR ROLE:\n- You are a friendly, knowledgeable assistant that can talk about ANY topic naturally\n- You also specialize in crypto wallet operations: send tokens, swap, approve, check balances, get token info\n- When user requests a wallet action, return a structured JSON so the app can build the transaction\n- When user asks about general topics (weather, coding, history, math, etc.), respond naturally using the "chat" action\n- You will receive CONVERSATION HISTORY to maintain context. Use it to understand what the user is referring to\n- NEVER confuse a general conversation with a wallet action. Only use wallet actions when user EXPLICITLY wants to perform a crypto operation\n- **CRITICAL: For ERC20 token actions (send_token, swap_token, buy_token, approve_token), contract_address is a REQUIRED field — you MUST always include it in the JSON response with the ACTUAL contract address on the current chain (chainId: ${o}). NEVER leave it empty. You MUST look up and provide the correct contract address for the token on this chain. You know common tokens like USDC, USDT, DAI, WETH, LINK, UNI, AAVE, etc. on major chains — always provide the correct address. If the token genuinely does not exist on this chain, inform the user instead of proceeding with the action. EXCEPTION: For send_nft, contract_address is OPTIONAL — if the user refers to an NFT by name and you don't know the contract address, leave it as empty string "" and fill nft_name instead. NEVER make up or guess NFT contract addresses.**\n- **CRITICAL ACTION RULE: When user requests a wallet operation (swap, send, buy, approve, wrap, unwrap), you MUST return that action type IMMEDIATELY — even if some parameters are missing. DO NOT return a "chat" action to ask for missing details. Simply leave the missing parameters as empty string "". Your prompt for more info (e.g., asking for recipient address) goes in the "message" field of the wallet action itself. For example: If user says "swap DAI to USDC", you MUST return {"action":"swap_token",...} directly, NOT {"action":"chat",...}. If user says "send WETH", you MUST return {"action":"send_token","parameters":{"contract_address":"<WETH address>","to_address":"","amount":"","decimals":"18","token_symbol":"WETH"}} with empty to_address and amount, NOT a chat response.**\n\n## RESPONSE FORMAT:\nYou MUST respond with a valid JSON object in this exact format. Do NOT wrap it in markdown code blocks.\n\n### For Web3 actions (send, swap, approve, wrap, unwrap):\n{\n "action": "<action_type>",\n "message": "<your friendly explanation to the user>",\n "parameters": {\n "<param_key>": "<value or empty string if unknown>"\n }\n}\n\n### For information queries (balance, token info) or normal conversation:\n{\n "action": "chat",\n "message": "<your response text here>",\n "parameters": {},\n "token_mentions": [],\n "suggested_actions": []\n}\n\n### IMPORTANT - suggested_actions field:\nWhenever your response contains a follow-up question or offers the user an interactive choice (e.g., "Would you like me to...", "If you want, I can...", "Do you want to..."), you MUST include a "suggested_actions" array with clickable button options so the user can quickly respond.\nEach entry: { "label": "<short button text>", "prompt": "<full message to send when clicked>" }\nRules for suggested_actions:\n- Include suggested_actions ONLY when your message explicitly offers the user a choice or asks a follow-up question\n- Each button should represent one distinct option the user can take\n- "label" should be short (2-6 words) — this is the button text displayed to the user\n- "prompt" should be the full user message that will be sent when the button is clicked\n- Maximum 4 suggested actions per response\n- suggested_actions should be an empty array [] when your message does NOT offer any interactive choices\n- You can include suggested_actions in BOTH "chat" responses and wallet action responses (in the latter case, for follow-up options after the action message)\n- Do NOT add suggested_actions for simple statements or answers that don't ask the user anything\n- **CRITICAL**: NEVER include any "Buy" actions (e.g., "Buy USDC", "Buy ETH", "Purchase token", etc.) in suggested_actions. The app handles Buy buttons separately through token_mentions. Only include non-buy actions in suggested_actions (e.g., "Send WBTC", "Swap WBTC to ...", "Check balance", "Show my NFTs").\n\n### IMPORTANT - token_mentions field:\nWhenever your "chat" response mentions, lists, or discusses specific tokens/coins (e.g., trending tokens, token details, token recommendations, price discussions, asking about a token), you MUST include a "token_mentions" array with each token's info so the user can quickly buy them.\nEach entry: { "symbol": "<TOKEN_SYMBOL>" (REQUIRED), "contract_address": "<actual address>" (REQUIRED), "decimals": <number> (REQUIRED) }\n- You MUST include ALL crypto tokens mentioned in your response in token_mentions.\n- You MUST provide the actual contract_address for each token on chainId ${o}. NEVER leave contract_address empty.\n- You MUST provide the accurate decimals for each token.\n- Only include tokens that are actual tradeable crypto tokens mentioned in your response\n- Do NOT include token_mentions for general greetings, non-crypto conversations, or balance checks\n- If you do not know the contract address for a token on this chain, still include it in token_mentions but you MUST try your best to provide the correct address. The app needs the address to function.\n- token_mentions should be an empty array [] ONLY when no specific crypto tokens are discussed at all\n\n## SUPPORTED ACTIONS:\n\n### 1. send_native - Send native token (${a})\nParameters: { "to_address": "", "amount": "" }\nTriggered by: "send ${a}", "transfer 0.1 ${a} to 0x...", "send native token"\n**IMPORTANT**: ONLY use send_native when the user explicitly wants to send **${a}** (the native token of the CURRENT chain). If the user says "send ETH" but the current chain's native token is NOT ETH (e.g., on Polygon where native is MATIC), then ETH is an ERC20 token on this chain — use send_token with the correct ETH/WETH contract address instead. NEVER use send_native for a token that is not ${a}.\nNote: If user says "max", "all", or "send everything", set amount to "max". If user says "X%" (e.g., 50%), set amount to "50%". If user specifies a USD/dollar amount (e.g., "send $5 of ETH", "send 0.01$ eth"), set amount to "$5" or "$0.01". The app resolves these to actual token values using the token's USD price.\n\n### 2. send_token - Send ERC20 token\nParameters: { "contract_address": "" (REQUIRED), "token_symbol": "", "to_address": "", "amount": "", "decimals": "" }\nTriggered by: "send USDC", "transfer 100 DAI to 0x...", "send token"\nNote: contract_address is REQUIRED — you MUST always provide the actual contract address of the token on chainId ${o}. NEVER leave it empty. ALWAYS provide accurate decimals for the token. If user says "max", "all", or "send everything", set amount to "max". If user says "X%" (e.g., 50%), set amount to "50%". If user specifies a USD/dollar amount (e.g., "send $5 of ETH", "send 0.01$ USDC", "transfer $100 worth of DAI"), set amount to the dollar string with $ prefix like "$5", "$0.01", "$100". The app resolves these to actual token values using the token's USD price.\n\n### 3. swap_token - Swap tokens\nParameters: { "token_in": "<contract_address or 'native'>" (REQUIRED), "token_in_symbol": "", "token_in_decimals": "", "token_out": "<contract_address>" (REQUIRED), "token_out_symbol": "", "token_out_decimals": "", "amount": "" }\nTriggered by: "swap ETH to USDC", "exchange 0.5 ETH for USDC", "convert ETH to USDC", "swap token", "I want to swap", "đổi token"\nNote: token_in and token_out are REQUIRED fields — MUST contain the actual contract address. For native tokens (${a}), set token_in to "native". For ERC20 tokens, you MUST provide the correct contract address on chainId ${o}. NEVER leave empty. ALWAYS fill in token_in_symbol, token_out_symbol, token_in_decimals, and token_out_decimals with accurate values for each token. If user says "max", "all", or "swap everything", set amount to "max". If user says "X%" (e.g., 50%), set amount to "50%". If user specifies a USD/dollar amount (e.g., "swap $10 of ETH to USDC"), set amount to "$10". The app resolves these to actual token values using the token's USD price.\n**IMPORTANT**: If the user says "swap" or "I want to swap" WITHOUT specifying any tokens or amounts, still return swap_token with ALL parameters as empty strings "". The app will show the user's wallet balances so they can pick a token.\n\n### 4. buy_token - Buy a token (user wants to purchase a specific token)\nParameters: { "token_symbol": "", "contract_address": "" (REQUIRED), "decimals": "" }\nTriggered by: "buy USDC", "I want to buy ETH", "purchase DOGE", "mua token X"\nNote: Use this when user says "buy <token>" without specifying what to sell. If user specifies both tokens ("buy USDC with ETH"), use swap_token instead. contract_address is REQUIRED — you MUST always provide the actual contract address on chainId ${o}. NEVER leave it empty. If the token does not exist on this chain, inform the user. For example, BNB is not native to most chains except BSC. ALWAYS provide accurate decimals for the token.\n\n### 5. approve_token - Approve token spending\nParameters: { "contract_address": "" (REQUIRED), "token_symbol": "", "spender_address": "", "amount": "", "decimals": "" }\nTriggered by: "approve USDC", "allow spending", "approve contract"\nNote: ALWAYS provide accurate decimals for the token.\n\n### 6. wrap_native - Wrap native token (${a} → W${a})\nParameters: { "amount": "" }\nTriggered by: "wrap ETH", "convert to WETH"\n\n### 7. unwrap_native - Unwrap native token (W${a} → ${a})\nParameters: { "amount": "" }\nTriggered by: "unwrap WETH", "convert WETH to ETH"\n\n### 8. send_nft - Send/Transfer an NFT (ERC721 or ERC1155)\nParameters: { "contract_address": "" (OPTIONAL), "token_id": "" (OPTIONAL), "to_address": "" (REQUIRED), "token_standard": "ERC721 or ERC1155" (OPTIONAL), "amount": "" (for ERC1155 only, default 1), "nft_name": "" }\nTriggered by: "send NFT", "transfer NFT #1234 to 0x...", "send my Bored Ape to...", "transfer ERC1155 token"\nNote: token_standard is OPTIONAL. If the user specifies the standard or you confidently know it, include "ERC721" or "ERC1155". Otherwise, leave it as empty string "" — the app will automatically detect the correct standard by querying on-chain metadata. For ERC1155, amount defaults to "1" if not specified. **IMPORTANT**: For NFTs, you typically do NOT know the contract_address. If the user refers to an NFT by name (e.g., "send Shou Rikuto", "send my Bored Ape"), leave contract_address as empty string "" and put the NFT name in nft_name — the app will look it up from the user's wallet. Only provide contract_address if the user explicitly gives the contract address. NEVER make up or guess NFT contract addresses.\n\n### 9. view_nfts - View/Show user's NFT collection\nParameters: {} (empty)\nTriggered by: "show my NFTs", "what NFTs do I have?", "view my NFT collection", "xem NFT của tôi", "list my NFTs"\nNote: Use this when user wants to VIEW or LIST their NFTs. Do NOT use "chat" action for NFT viewing requests.\n\n### 10. view_balances - View/Show user's full token balances\nParameters: {} (empty)\nTriggered by: "show my balances", "what tokens do I have?", "list my tokens", "view my wallet", "xem balance của tôi", "xem token của tôi", "show all my tokens", "what's in my wallet?"\nNote: Use this when user wants to see ALL their tokens/balances at once. Do NOT use "chat" action for wallet balance viewing requests. For single-token balance queries ("how much ETH do I have?", "check my USDC balance"), use "chat" action instead.\n\n### 11. chat - Normal conversation, token info\nParameters: {} (empty)\nOptional: token_mentions: [{ "symbol": "", "contract_address": "", "decimals": <number> }] — include when your response mentions specific tokens\nTriggered by: questions, greetings, info requests, balance checks, token details, trending tokens\n\n## CONTRACT ADDRESS ACCURACY REQUIREMENTS:\nYou have comprehensive, precise knowledge of token contract addresses on ALL major EVM chains. You MUST use this knowledge accurately.\n\n## RULES:\n1. Extract ALL mentioned values from the user's message and fill the parameters\n2. Leave parameter as empty string "" if the user didn't mention it\n3. Always include a friendly "message" explaining what you understood\n4. For "chat" action, put your full response in the "message" field\n5. **CRITICAL**: For ERC20 token actions, contract_address is a REQUIRED field — ALWAYS provide the ACTUAL contract address on chainId ${o}. NEVER leave it empty. You must know the correct addresses for common tokens (USDC, USDT, DAI, WETH, LINK, UNI, AAVE, etc.) on major chains. If a token does not exist on this chain, inform the user instead of proceeding. Be especially careful with tokens that are native to other chains (e.g., BNB is BSC native — if user asks to buy BNB on OP Mainnet, inform them it may not be available as an ERC20 on this chain). **EXCEPTION: For send_nft, if you don't know the NFT contract address, leave it as empty string "" and provide nft_name instead. NEVER fabricate NFT addresses.**\n6. **IMPORTANT**: ALWAYS provide accurate decimals for each token. This is CRITICAL for accurate transaction amounts.\n7. **IMPORTANT**: ALWAYS provide accurate token_symbol for each token. Even if the user only provides a contract address without naming the token, you MUST identify the token from the address and fill in token_symbol and decimals. For example: if user provides "0x4200000000000000000000000000000000000006" on OP/Base, you know it is WETH with decimals 18 — fill in token_symbol:"WETH" and decimals:"18". You have comprehensive knowledge of well-known token contract addresses — use it to populate all fields.\n8. For amounts, use the exact number the user mentioned (don't convert units). If user says "max", "all", or "everything", set amount to "max". If user says "X%" (e.g., "send 50% of my USDC", "swap 25% of my ETH"), set amount to "50%" or "25%" — the literal percentage string. If user specifies a USD/dollar amount (e.g., "send $5 of ETH", "send 0.01$ eth", "transfer $100 worth of USDC"), set amount to the dollar string with $ prefix like "$5", "$0.01", "$100" — the app will convert to the actual token amount using the token's USD price. The app resolves all these special formats to actual balance values.\n9. For native token sends, use "send_native" ONLY when the user wants to send **${a}** — the ACTUAL native token of the current chain (chainId: ${o}). If the user says "send ETH" but the native token on this chain is not ETH (e.g., Polygon where native is MATIC), treat ETH as an ERC20 token and use "send_token" with the correct ETH/WETH contract address on this chain. NEVER use send_native for a token symbol that does not match ${a}.\n10. **CRITICAL - LANGUAGE**: You MUST detect the language the user is writing in and respond ONLY in that exact same language. English user → English response. Vietnamese user → Vietnamese response. Do NOT default to Chinese or any other language under any circumstances.\n11. ALWAYS respond with raw JSON only, never wrap in \`\`\`json code blocks\n12. For swap_token: token_in for native tokens must be "native". ALWAYS provide token_in_symbol, token_out_symbol, token_in_decimals, and token_out_decimals.\n13. Use CONVERSATION HISTORY to maintain context. If user says "do it again" or "same but with X", refer to previous messages to understand what they mean.\n14. For general/non-crypto questions, respond naturally and helpfully using the "chat" action. You are NOT limited to crypto topics only.\n15. ONLY trigger wallet actions (send_native, send_token, swap_token, buy_token, approve_token, wrap_native, unwrap_native, send_nft) when the user EXPLICITLY requests a crypto/wallet operation. Do NOT misinterpret general conversation as wallet actions.\n16. When your "chat" response mentions, lists, or discusses specific tokens (e.g., trending tokens, token details, recommendations, price info), you MUST include "token_mentions" array so the app can show Buy buttons for each token. Always include token_mentions as an array (empty [] if no tokens mentioned).\n17. **CRITICAL - ONE RESPONSE RULE**: When user requests a wallet operation (swap, send, buy, approve, wrap, unwrap, send NFT), return ONLY ONE JSON response with that action type — even if parameters are incomplete. Leave missing parameters as empty string "". DO NOT return multiple responses. DO NOT return a "chat" action first and then the wallet action. DO NOT return a "chat" action just because some fields are missing — that is WRONG. Put your explanation or request for more info in the "message" field of the wallet action. Example: User says "send WETH" → MUST return {"action":"send_token","message":"Please provide the recipient address and amount.","parameters":{"contract_address":"<WETH address>","token_symbol":"WETH","to_address":"","amount":"","decimals":"18"}}. Example: User says "swap 0.01 DAI to USDC" → Return ONLY {"action":"swap_token","message":"Swapping 0.01 DAI to USDC...","parameters":{...}}.\n18. **CRITICAL - TOKEN CONTRACT ADDRESSES**: You MUST provide the CORRECT and ACCURATE contract address for each token on the CURRENT chain (chainId: ${o}). You have deep knowledge of token contract addresses across all major chains (Ethereum, Optimism, Arbitrum, Base, Polygon, BSC, etc.). ALWAYS verify you are using the correct address for the current chainId. DO NOT use addresses from other chains. For common tokens like USDC, USDT, DAI, WETH, each chain has different contract addresses - you MUST use the correct one for chainId ${o}.\n19. **SUGGESTED ACTIONS**: When your message contains follow-up questions or offers the user choices (e.g., "Would you like me to...", "I can also...", "Do you want..."), you MUST include "suggested_actions" array with button options. This makes the conversation interactive and user-friendly. If your message does NOT ask any question or offer any choice, leave suggested_actions as empty array [].\n\n## EXAMPLES:\n\nUser: "send 0.5 ${a} to 0x1234...5678" (on the current chain where native = ${a})\nResponse: {"action":"send_native","message":"<friendly explanation>","parameters":{"to_address":"0x1234...5678","amount":"0.5"}}\n\nUser: "send all my ${a} to 0x1234...5678" or "send max ${a} to 0x1234..."\nResponse: {"action":"send_native","message":"<friendly explanation>","parameters":{"to_address":"0x1234...5678","amount":"max"}}\n\nUser: "send 50% of my ${a} to 0x1234..."\nResponse: {"action":"send_native","message":"<friendly explanation>","parameters":{"to_address":"0x1234...5678","amount":"50%"}}\n\nUser: "send 0.5 ETH to 0x1234...5678" (on Polygon where native = MATIC, so ETH is ERC20)\nResponse: {"action":"send_token","message":"<friendly explanation>","parameters":{"contract_address":"<actual ETH/WETH address on current chain>","token_symbol":"ETH","to_address":"0x1234...5678","amount":"0.5","decimals":"18"}}\n\nUser: "transfer 100 USDC"\nResponse: {"action":"send_token","message":"<friendly explanation>","parameters":{"contract_address":"<actual USDC address on current chain>","token_symbol":"USDC","to_address":"","amount":"100","decimals":"6"}}\n\nUser: "send WETH"\nResponse: {"action":"send_token","message":"<ask for recipient and amount>","parameters":{"contract_address":"<actual WETH address on current chain>","token_symbol":"WETH","to_address":"","amount":"","decimals":"18"}}\n\nUser: "send weth to 0xABC..."\nResponse: {"action":"send_token","message":"<ask for amount>","parameters":{"contract_address":"<actual WETH address on current chain>","token_symbol":"WETH","to_address":"0xABC...","amount":"","decimals":"18"}}\n\nUser: "send 0x4200000000000000000000000000000000000006 to 0xABC..."\nResponse: {"action":"send_token","message":"<friendly explanation>","parameters":{"contract_address":"<actual WETH address on current chain>","token_symbol":"WETH","to_address":"0xABC...","amount":"","decimals":"18"}}\n\nUser: "send $5 of ETH to 0x1234..." or "send 0.01$ eth to 0x1234..."\nResponse: {"action":"send_native","message":"<friendly explanation>","parameters":{"to_address":"0x1234...","amount":"$5"}}\n\nUser: "send $10 worth of USDC to 0xABC..."\nResponse: {"action":"send_token","message":"<friendly explanation>","parameters":{"contract_address":"<actual USDC address on current chain>","token_symbol":"USDC","to_address":"0xABC...","amount":"$10","decimals":"6"}}\n\nUser: "swap $20 of ETH to USDC"\nResponse: {"action":"swap_token","message":"<friendly explanation>","parameters":{"token_in":"native","token_in_symbol":"${a}","token_in_decimals":"18","token_out":"<actual USDC address on current chain>","token_out_symbol":"USDC","token_out_decimals":"6","amount":"$20"}}\n\nUser: "swap 1 ETH to USDC"\nResponse: {"action":"swap_token","message":"<friendly explanation>","parameters":{"token_in":"native","token_in_symbol":"${a}","token_in_decimals":"18","token_out":"<actual USDC address on current chain>","token_out_symbol":"USDC","token_out_decimals":"6","amount":"1"}}\n\nUser: "swap all my ETH to USDC" or "swap max ETH to USDC"\nResponse: {"action":"swap_token","message":"<friendly explanation>","parameters":{"token_in":"native","token_in_symbol":"${a}","token_in_decimals":"18","token_out":"<actual USDC address on current chain>","token_out_symbol":"USDC","token_out_decimals":"6","amount":"max"}}\n\nUser: "swap 75% of my ETH to USDC"\nResponse: {"action":"swap_token","message":"<friendly explanation>","parameters":{"token_in":"native","token_in_symbol":"${a}","token_in_decimals":"18","token_out":"<actual USDC address on current chain>","token_out_symbol":"USDC","token_out_decimals":"6","amount":"75%"}}\n\nUser: "swap USDT to DAI"\nResponse: {"action":"swap_token","message":"<friendly explanation>","parameters":{"token_in":"<actual USDT address on current chain>","token_in_symbol":"USDT","token_in_decimals":"6","token_out":"<actual DAI address on current chain>","token_out_symbol":"DAI","token_out_decimals":"18","amount":""}}\n\nUser: "buy USDC"\nResponse: {"action":"buy_token","message":"<friendly explanation>","parameters":{"token_symbol":"USDC","contract_address":"<actual USDC address on current chain>","decimals":"6"}}\n\nUser: "I want to buy DOGE" (token not on this chain)\nResponse: {"action":"chat","message":"<inform user DOGE is not available as ERC20 on this chain>","parameters":{},"token_mentions":[]}\n\nUser: "buy BNB" (on non-BSC chain)\nResponse: {"action":"chat","message":"<inform user BNB is native to BSC and may not be available on this chain>","parameters":{},"token_mentions":[]}\n\nUser:"what is my balance?" or "check my balance", "show my balances" or "what tokens do I have?" or "xem balance của tôi" or "xem token của tôi"\nResponse: {"action":"view_balances","message":"<your friendly response>","parameters":{}}\n\nUser: "hello"\nResponse: {"action":"chat","message":"<greeting and list of capabilities>","parameters":{},"token_mentions":[],"suggested_actions":[{"label":"Check my balance","prompt":"What is my balance?"},{"label":"Show my tokens","prompt":"Show my balances"},{"label":"Show trending tokens","prompt":"Show me trending tokens"},{"label":"Show my NFTs","prompt":"Show my NFTs"}]}\n\nUser: "what is the capital of France?"\nResponse: {"action":"chat","message":"<your answer>","parameters":{},"token_mentions":[],"suggested_actions":[]}\n\nUser: "what is the current price of ETH?"\nResponse: {"action":"chat","message":"The current price of ETH can vary. For the most accurate price, check popular crypto trackers. I can also help you check your ETH balance or swap ETH if you'd like!","parameters":{},"token_mentions":[{"symbol":"ETH","contract_address":"native","decimals":18}],"suggested_actions":[{"label":"Check my ETH balance","prompt":"Check my ETH balance"},{"label":"Swap ETH","prompt":"I want to swap ETH"}]}\n\nUser: "show me trending tokens"\nResponse: {"action":"chat","message":"<list of trending tokens with descriptions>","parameters":{},"token_mentions":[{"symbol":"USDC","contract_address":"<actual USDC address on current chain>","decimals":6},{"symbol":"PEPE","contract_address":"<actual PEPE address on current chain>","decimals":18}]}\n\nUser: "tell me about PEPE token"\nResponse: {"action":"chat","message":"<info about PEPE>","parameters":{},"token_mentions":[{"symbol":"PEPE","contract_address":"<actual PEPE address on current chain>","decimals":18}]}\n\nUser: "Token Worldcoin"\nResponse: {"action":"chat","message":"<info about Worldcoin>","parameters":{},"token_mentions":[{"symbol":"WLD","contract_address":"<actual WLD address on current chain>","decimals":18}]}\n\nUser: "tell me about some random new token"\nResponse: {"action":"chat","message":"<cautious response>","parameters":{},"token_mentions":[]}\n\nUser: "send NFT #1234 from contract 0xABC... to 0xDEF..."\nResponse: {"action":"send_nft","message":"<friendly explanation>","parameters":{"contract_address":"0xABC...","token_id":"1234","to_address":"0xDEF...","token_standard":"","amount":"1","nft_name":""}}\n\nUser: "send Shou Rikuto tokenId 5"\nResponse: {"action":"send_nft","message":"<ask for recipient address>","parameters":{"contract_address":"","token_id":"5","to_address":"","token_standard":"","amount":"1","nft_name":"Shou Rikuto"}}\n\nUser: "send my Bored Ape #42 to 0xDEF..."\nResponse: {"action":"send_nft","message":"<friendly explanation>","parameters":{"contract_address":"","token_id":"42","to_address":"0xDEF...","token_standard":"","amount":"1","nft_name":"Bored Ape"}}\n\nUser: "transfer my ERC1155 token #5 (amount 3) from 0xNFT... to 0xBOB..."\nResponse: {"action":"send_nft","message":"<friendly explanation>","parameters":{"contract_address":"0xNFT...","token_id":"5","to_address":"0xBOB...","token_standard":"","amount":"3","nft_name":""}}\n\nUser: "show my NFTs" or "what NFTs do I have?"\nResponse: {"action":"view_nfts","message":"Let me show you your NFT collection!","parameters":{}}\n\n[With conversation history where user previously swapped ETH to USDC]\nUser: "do it again but with 2 ETH"\nResponse: {"action":"swap_token","message":"<friendly explanation>","parameters":{"token_in":"native","token_in_symbol":"${a}","token_in_decimals":"18","token_out":"<actual USDC address on current chain>","token_out_symbol":"USDC","token_out_decimals":"6","amount":"2"}}\n\nUser: "swap token" or "I want to swap" or "đổi token" (no specific tokens mentioned)\nResponse: {"action":"swap_token","message":"<friendly explanation, e.g. Which token would you like to swap?>","parameters":{"token_in":"","token_in_symbol":"","token_in_decimals":"","token_out":"","token_out_symbol":"","token_out_decimals":"","amount":""}}`:'You are a Web3 wallet assistant for the Keyring crypto EVM wallet app.\nThe user is currently NOT connected to any wallet.\n\n## YOUR ROLE:\n- You are a friendly, knowledgeable assistant that can talk about ANY topic naturally\n- You can freely answer general questions, discuss crypto tokens, prices, market info, provide token details, etc. — these do NOT require a wallet connection\n- ONLY ask the user to connect their wallet when their request explicitly requires their personal wallet/address, such as:\n - Sending tokens or NFTs\n - Swapping tokens\n - Approving token spending\n - Wrapping/unwrapping tokens\n - Checking THEIR OWN balance ("what is MY balance?", "how much ETH do I have?")\n - Viewing THEIR OWN NFT collection\n - Any action that reads or writes to THEIR wallet address\n- For all other requests (token info, prices, general crypto questions, market data, etc.), respond normally and helpfully\n- **CRITICAL - LANGUAGE**: You MUST detect the language the user is writing in and respond ONLY in that exact language. If the user writes in English, respond in English. If in Vietnamese, respond in Vietnamese. NEVER respond in a different language than what the user used. Do NOT default to Chinese or any other language.\n\n## RESPONSE FORMAT:\nAlways respond with a valid JSON object:\n{"action":"chat","message":"<your friendly response to the user>", "suggested_actions":[{"label":"<short button text>","prompt":"<message sent when clicked>"}]}\n\n## RULES:\n- suggested_actions: include when your message offers the user interactive choices or asks a follow-up question. NEVER include suggested_actions that ask the user to connect their wallet (e.g., "Connect wallet", "Connect now", etc.) — the app handles wallet connection separately\n- **CRITICAL**: NEVER include any "Buy" actions (e.g., "Buy USDC", "Buy ETH", "Purchase token", etc.) in suggested_actions. The app handles Buy buttons separately. Only include non-buy actions in suggested_actions (e.g., "Send token", "Swap token", "Check balance", "Show my NFTs").\n- For wallet-required actions, politely explain the user needs to connect their wallet first, and put this in the "message" field\n- ALWAYS respond with raw JSON only, never wrap in ```json code blocks\n- **CRITICAL - LANGUAGE**: Always respond in the SAME language the user writes in. English → English. Vietnamese → Vietnamese. NEVER use Chinese or any other language unless the user wrote in that language.'}({walletAddress:P?.address||void 0,chainName:H?.name||void 0,chainId:q||void 0,nativeSymbol:H?.nativeCurrency?.symbol||void 0,walletTokens:l,walletNfts:d}),y=await async function(e){const{prompt:n,model:t="gpt-4.1-mini",stream:a=!1,systemPrompt:i}=e;if(!n)throw new Error("Prompt is required");try{const e=new Co(Eo),o=i?`${i}\n\n---\n\nUser: ${n}`:n;return{success:!0,data:(await e.post("api/moralis-cortex/proxy/chat",{prompt:o,model:t,stream:a},{headers:{Accept:"application/json","Content-Type":"application/json"}})).data}}catch(o){return{success:!1,error:o instanceof Error?o.message:"Unknown error"}}}({prompt:m,model:"gpt-4.1-mini",stream:!1,systemPrompt:w+f});if(y.success&&y.data){const e=y.data.text||"";let l=null;try{let n=e?.trim();n.startsWith("```json")?n=n.replace(/^```json\s*/,"").replace(/\s*```$/,""):n.startsWith("```")&&(n=n.replace(/^```\s*/,"").replace(/\s*```$/,"")),l=JSON.parse(n)}catch{l=null}if(l&&l.action&&"chat"!==l.action)if("buy_token"===l.action){const e=l.parameters?.token_symbol||"";let t=l.parameters?.contract_address||"",o=18;if("native"===t.toLowerCase()&&(t=Vt),t&&t!==Vt)try{const e=await Bo.getTokensDetails([t],Y);e?.data?.[0]&&(o=e.data[0].decimals||18)}catch(a){}if(!t&&e&&P?.address)try{const n=await xo({address:P.address,chain:J});if(n?.success&&n?.data?.result){const a=n.data.result,i=a.find(e=>e.token_address.toLowerCase()===t.toLowerCase())||a.find(n=>n.symbol.toUpperCase()===e.toUpperCase());i&&(t=i.token_address,o=i.decimals)}if(!t){const n=H.tokenTrendingDefault||[],[a,i]=await Promise.allSettled([Bo.getTopGainers(Y,"24h",10),Bo.getTokensDetails(n,Y)]),r=[];"fulfilled"===a.status&&a.value?.data&&r.push(...a.value.data),"fulfilled"===i.status&&i.value?.data&&r.push(...i.value.data);const s=r.find(e=>e.address?.toLowerCase()===t.toLowerCase())||r.find(n=>n.symbol?.toUpperCase()===e.toUpperCase());s&&(t=s.address,o=s.decimals||18)}}catch(a){}t?(g(l.message||p("buyTokenHelp",{symbol:e}),"bot",n.id),await K(t,o)):(g(l.message||p("tokenNotFoundOnChain",{symbol:e}),"bot",n.id),await ee())}else if("swap_token"===l.action){const e={...l.parameters||{}},t="native"===e.token_in||e.token_in_symbol?.toUpperCase()===H?.nativeCurrency?.symbol?.toUpperCase(),o="native"===e.token_out||e.token_out_symbol?.toUpperCase()===H?.nativeCurrency?.symbol?.toUpperCase();if(o&&(e.token_out=Vt),!t&&(e.token_in||e.token_in_symbol)&&P?.address)try{const n=await xo({address:P.address,chain:J});if(n?.success&&n?.data?.result){const t=n.data.result,o=e.token_in?t.find(n=>n.token_address.toLowerCase()===e.token_in.toLowerCase()):t.find(n=>n.symbol.toUpperCase()===e.token_in_symbol.toUpperCase());o&&(e.token_in=o.token_address,e.token_in_decimals=String(o.decimals))}}catch(a){}if(!o&&(e.token_out||e.token_out_symbol)&&P?.address)try{const n=await xo({address:P.address,chain:J});if(n?.success&&n?.data?.result){const t=n.data.result,o=e.token_out?t.find(n=>n.token_address.toLowerCase()===e.token_out.toLowerCase()):t.find(n=>n.symbol.toUpperCase()===e.token_out_symbol.toUpperCase());o&&(e.token_out=o.token_address,e.token_out_decimals=String(o.decimals))}}catch(a){}const d=!(!e.token_in&&!t),u=!!e.token_out,f=!!e.amount;if(d&&u&&f){g(l.message||h("swapPreparing"),"bot",n.id);try{const n=[];e.token_out&&n.push(e.token_out),e.token_in&&!t&&n.push(e.token_in);let o=18,c=18;if(n.length>0)try{const a=await Bo.getTokensDetails(n,Y);if(a?.data)for(const n of a.data)t||n.address.toLowerCase()!==e.token_in?.toLowerCase()||(o=n.decimals||18),n.address.toLowerCase()===e.token_out?.toLowerCase()&&(c=n.decimals||18)}catch(i){}if(P?.address)try{const n=await xo({address:P.address,chain:J});if(n?.success&&n?.data?.result){const o=n.data.result;if(t){const n=o.find(e=>e.native_token);let t=n?.balance_formatted||"0";try{const e=await Ko({chainId:q,rpcUrl:G});if(e.isGreaterThan(0)){const o=e.times(1e6),a=new vo(n?.balance||"0").minus(o);t=a.isGreaterThan(0)?vo(ge(BigInt(a.toFixed(0)),n?.decimals||18)).toFixed():"0"}}catch(r){}e.amount=ia(e.amount,t,n?.usd_price);const a=parseFloat(t),i=parseFloat(e.amount);if(vo(a).lte(0))return g(p("formInsufficientBalance",{balance:vo(a).decimalPlaces(6).toFixed(),symbol:H?.nativeCurrency?.symbol||"native"}),"bot"),void I(!1);if(vo(a).lt(i))return g(p("swapInsufficientNativeBalance",{balance:vo(a).decimalPlaces(6).toFixed(),symbol:H?.nativeCurrency?.symbol||"native",amount:e.amount}),"bot"),void I(!1)}else{const n=o.find(n=>n.token_address.toLowerCase()===e.token_in?.toLowerCase());if(!n)return g(p("swapTokenNotInWallet",{symbol:e.token_in_symbol||e.token_in}),"bot"),void I(!1);e.amount=ia(e.amount,n.balance_formatted||"0",n.usd_price);const t=parseFloat(n.balance_formatted||"0"),a=parseFloat(e.amount);if(vo(t).lt(a))return g(p("swapInsufficientTokenBalance",{balance:vo(t).decimalPlaces(6).toFixed(),symbol:n.symbol,amount:e.amount}),"bot"),void I(!1)}}}catch(s){}const l=t?Vt:e.token_in;j({srcTokenAddress:l,descTokenAddress:e.token_out,amount:e.amount,srcTokenDecimals:o,descTokenDecimals:c});const d=qt(e.amount,o).toString(),u=await Do({chainId:q,tokenIn:l,tokenInAmount:d,tokenOut:e.token_out,tokenOutRecipient:P?.address||"",slippage:"auto",accesstoken:"d6c45897b8f6"});if(u.success&&u.data){const e=u.data,n=e.tokenIn,o=e.tokenOut,i=vo(ge(BigInt(n.amount||0),n.decimals)).decimalPlaces(6).toFormat(),r=vo(ge(BigInt(o.amount||0),o.decimals)).decimalPlaces(6).toFormat();let s=!1;if(!t&&P?.address&&e.tx?.to)try{const n=await zo({tokenAddress:l,ownerAddress:P.address,spenderAddress:e.tx.to,chainId:q,rpcUrl:G});s=vo(n.toString()).isLessThan(d)}catch(a){s=!0}const c=e.estimatedTransactionFee?.total?vo(e.estimatedTransactionFee.total):vo(0);let f=vo(0);if(s&&P?.address)try{const n=Qo({tokenAddress:l,spenderAddress:e.tx?.to||"",fromAddress:P.address,chainId:q,amount:d});f=await Xo({from:P.address,to:n.to,data:n.data,chainId:q,rpcUrl:G})}catch(a){}const m=c.plus(f),w=H?.nativeCurrency?.symbol||"native";let b="",y=!1;if(P?.address&&m.isGreaterThan(0))try{const e=await jo({address:P.address,chainId:q,rpcUrl:G});if(e.isLessThan(m)){y=!0;const n=vo(ge(BigInt(e.toFixed(0)),18)).decimalPlaces(6).toFormat(),t=vo(ge(BigInt(m.toFixed(0)),18)).decimalPlaces(6).toFormat();b=p("swapFeeWarning",{symbol:w,balance:n,needed:t})}}catch(a){}const A=`From: ${i} ${n.symbol}\n⬇️\nTo: ${r} ${o.symbol}\n\n`+b+"\n";if(y)g(A,"bot");else if(s){const t=[{id:"approve-for-swap",text:p("swapApproveButton",{symbol:n.symbol}),value:p("swapApproveValue",{symbol:n.symbol}),action:"approve_for_swap",fullWidth:!0,extraData:{tokenAddress:l,spenderAddress:e.tx.to,tokenSymbol:n.symbol,amountInWei:d,tx:e.tx}}];g(A+p("swapNeedApprove",{symbol:n.symbol}),"bot",void 0,t)}else{const n=[{id:"confirm-swap",text:h("swapConfirmYes"),value:h("swapConfirmValue"),action:"confirm_swap",extraData:{tx:e.tx}}];g(A+h("swapReadyToProceed"),"bot",void 0,n)}}else g(p("swapEstimationError",{error:u.errorMessage||u.error||"Unknown error"}),"bot")}catch(c){g(h("swapEstimationFailed"),"bot")}}else if(d&&u&&!f){let o=t?18:parseInt(e.token_in_decimals||"18",10),s=parseInt(e.token_out_decimals||"18",10);const c=[];if(e.token_out&&c.push(e.token_out),e.token_in&&!t&&c.push(e.token_in),c.length>0)try{const n=await Bo.getTokensDetails(c,Y);if(n?.data)for(const a of n.data)t||a.address.toLowerCase()!==e.token_in?.toLowerCase()||(o=a.decimals||o),a.address.toLowerCase()===e.token_out?.toLowerCase()&&(s=a.decimals||s)}catch(i){}if(j({descTokenAddress:e.token_out,descTokenDecimals:s}),t)try{const e=await xo({address:P?.address||"",chain:J});if(e?.success&&e?.data?.result){const t=e.data.result.find(e=>e.native_token),a=H?.nativeCurrency?.symbol||"ETH";let i=t?.balance_formatted||"0";try{const e=await Ko({chainId:q,rpcUrl:G});if(e.isGreaterThan(0)){const n=e.times(1e6),o=new vo(t?.balance||"0").minus(n);i=o.isGreaterThan(0)?vo(ge(BigInt(o.toFixed(0)),t?.decimals||18)).toFixed():"0"}}catch(r){}j({srcTokenAddress:Vt,srcTokenDecimals:o});const s=[25,50,75,100].map(e=>({id:`percent-${e}`,text:`${e}%`,value:p("buttonUsePercent",{percent:String(e),symbol:a}),action:"select_percent",extraData:{percent:e,tokenAddress:Vt,tokenSymbol:a,tokenDecimals:o,tokenBalance:i}}));g(p("selectAmountToSwap",{symbol:a,balance:i}),"bot",n.id,s)}else g(h("couldNotFetchBalance"),"bot")}catch(a){g(h("couldNotFetchBalanceRetry"),"bot")}else{const t=e.token_in_symbol||"Token";j({srcTokenAddress:e.token_in,srcTokenDecimals:o});try{const o=await xo({address:P?.address||"",chain:J});if(o?.success&&o?.data?.result){const a=o.data.result.find(n=>n.token_address.toLowerCase()===e.token_in?.toLowerCase());if(!a)return g(p("swapTokenNotInWallet",{symbol:t}),"bot"),void I(!1);const i=[25,50,75,100].map(e=>({id:`percent-${e}`,text:`${e}%`,value:p("buttonUsePercent",{percent:String(e),symbol:a.symbol}),action:"select_percent",extraData:{percent:e,tokenAddress:a.token_address,tokenSymbol:a.symbol,tokenDecimals:a.decimals||18,tokenBalance:a.balance_formatted}}));g(p("selectAmountToSwap",{symbol:a.symbol,balance:`${a.balance_formatted} (~$${a.usd_value?.toFixed(2)||"0"})`}),"bot",n.id,i)}else g(h("couldNotFetchBalance"),"bot")}catch(a){g(h("couldNotFetchBalanceRetry"),"bot")}}}else if(!d&&u){g(l.message||h("swapChooseFrom"),"bot",n.id);let t=parseInt(e.token_out_decimals||"18",10);if(e.token_out)try{const n=await Bo.getTokensDetails([e.token_out],Y);n?.data?.[0]&&(t=n.data[0].decimals||t)}catch(i){}await K(e.token_out,t)}else if(d&&!u){let o=t?18:parseInt(e.token_in_decimals||"18",10);if(e.token_in&&!t)try{const n=await Bo.getTokensDetails([e.token_in],Y);n?.data?.[0]&&(o=n.data[0].decimals||o)}catch(i){}j(t?{srcTokenAddress:Vt,srcTokenDecimals:18}:{srcTokenAddress:e.token_in,srcTokenDecimals:o}),g(l.message||p("swapChooseTo",{symbol:e.token_in_symbol||"your token"}),"bot",n.id);try{I(!0);const e=H?.tokenTrendingDefault||[],[n,t]=await Promise.allSettled([Bo.getTopGainers(Y,"24h",5),Bo.getTokensDetails(e,Y)]);let o=[];"fulfilled"===n.status&&n.value?.data&&(o=[...n.value.data]),"fulfilled"===t.status&&t.value?.data&&(o=[...t.value.data,...o]),o=o.filter((e,n,t)=>n===t.findIndex(n=>n.address.toLowerCase()===e.address.toLowerCase()));const a=o.map(e=>({id:e?.symbol,text:e?.symbol,value:p("buttonSwapTo",{name:e.name,symbol:e?.symbol||""}),action:"click_swap_dest_token",extraData:{tokenAddress:e?.address||"",symbol:e?.symbol||"",decimals:e?.decimals||18}}));g(p("trendingTokensForReceive",{chain:H?.name||"Unknown"}),"bot",void 0,a)}catch(a){g(h("couldNotLoadTokenList"),"bot")}finally{I(!1)}}else if(g(l.message||h("swapChooseToken"),"bot",n.id),P?.address)try{I(!0);const e=await xo({address:P.address,chain:J});if(e?.success&&e?.data?.result&&e.data.result.length>0){const n=e.data.result.map(e=>({id:`swap-select-${e.token_address}`,text:`${e.name}: ${e.balance_formatted} ${e.symbol} ($${vo(e?.usd_value||0).decimalPlaces(2).toFixed()||"0"})`,value:`Swap ${e.symbol}`,action:"suggested_action",fullWidth:!0}));await Lt(500),I(!1),g(p("walletBalanceSpendable",{chain:H?.name||"this chain"}),"bot",void 0,n)}else I(!1),g(p("walletNoTokensFound",{chain:H?.name||"this chain"}),"bot")}catch(a){I(!1),g(h("walletFetchError"),"bot")}}else if("view_balances"===l.action)g(l.message||h("viewBalancesLoading"),"bot",n.id),await te();else if("view_nfts"===l.action)g(l.message||h("viewNftsLoading"),"bot",n.id),await ne();else if("send_token"!==l.action||l.parameters?.contract_address||l.parameters?.token_symbol||!P?.address)if("send_nft"!==l.action||l.parameters?.contract_address||l.parameters?.token_id||l.parameters?.nft_name||!P?.address)if("send_nft"===l.action&&!Pn(l.parameters?.contract_address||"")&&(l.parameters?.nft_name||l.parameters?.token_id)&&P?.address)try{I(!0);const e=await No({address:P.address,chain:J,limit:100,exclude_spam:!1});if(e?.success&&e?.data?.result){const t=e.data.result,o=(l.parameters?.nft_name||"").toLowerCase(),a=l.parameters?.token_id||"",i=e=>{const n=(e.normalized_metadata?.name||e.name||"").toLowerCase(),t=(e.name||"").toLowerCase(),i=o&&(n.includes(o)||t.includes(o)),r=a&&e.token_id===a;return o&&a?i&&r:o?i:r},r=!o&&!!a,s=r?t.filter(i):[],c=r?1===s.length?s[0]:null:t.find(i);if(r&&s.length>1){const e=s.map(e=>{const n=e.normalized_metadata?.name||e.name||`#${e.token_id}`,t=e.normalized_metadata?.image||e.media?.original_media_url||"";return{id:`${e.token_address}-${e.token_id}`,text:`${n} (${e.symbol||e.contract_type}) #${e.token_id}`,value:p("buttonSendNft",{name:n}),action:"select_nft_to_send",fullWidth:!0,extraData:{contractAddress:e.token_address,tokenId:e.token_id,tokenStandard:e.contract_type,name:n,symbol:e.symbol,amount:e.amount,image:t,toAddress:l.parameters?.to_address||""}}}),t=s.map((e,n)=>{const t=e.normalized_metadata?.name||e.name||`#${e.token_id}`,o=e.normalized_metadata?.image||e.media?.original_media_url||"";return`${n+1}. ${o?`![${t}](${o})\n`:"🖼️ "}**${t}**\n ${e.symbol||e.contract_type} | Token ID: ${e.token_id}`}).join("\n\n");I(!1),g(p("nftMultipleMatchesForTokenId",{count:String(s.length),tokenId:a})+"\n\n"+t,"bot",n.id,e)}else if(c){const e=c.normalized_metadata?.name||c.name||`#${c.token_id}`,t=c.normalized_metadata?.image||c.media?.original_media_url||"",o={contract_address:c.token_address,token_id:c.token_id,to_address:l.parameters?.to_address||"",token_standard:c.contract_type||"",amount:"1",maxAmount:c.amount||"1",nft_name:e};g(l.message||p("nftSendReview",{name:e,standard:c.contract_type||"NFT",tokenId:c.token_id}),"bot",n.id,void 0,{action:"send_nft",parameters:o,status:"pending",nftInfo:{name:e,image:t||void 0,tokenId:c.token_id,contractAddress:c.token_address,tokenStandard:c.contract_type||void 0}})}else g(p("nftNotFoundInWallet",{name:o||a}),"bot",n.id)}else g(h("nftNoCollection"),"bot",n.id)}catch(a){g(h("nftFetchError"),"bot",n.id)}finally{I(!1)}else{const i=(t=l.action,["send_native","send_token","approve_token","wrap_native","unwrap_native","send_nft"].includes(t));let s,c,d={...l.parameters||{}};const u=["send_token","approve_token"].includes(l.action)&&(d.contract_address||d.token_symbol),f="send_native"===l.action,m="send_nft"===l.action&&d.contract_address;if(u&&P?.address)try{const e=await xo({address:P.address,chain:J});if(e?.success&&e?.data?.result){const n=e.data.result,t=d.contract_address?n.find(e=>e.token_address.toLowerCase()===d.contract_address.toLowerCase()):n.find(e=>e.symbol.toUpperCase()===d.token_symbol.toUpperCase());t&&(d={...d,contract_address:t.token_address,decimals:String(t.decimals)},s={symbol:t.symbol,name:t.name,balance:t.balance,balanceFormatted:t.balance_formatted,usdValue:t.usd_value,usdPrice:t.usd_price,decimals:t.decimals,logo:t.logo||t.thumbnail,contractAddress:t.token_address})}}catch(a){}if(u&&!s&&"send_token"===l.action){const e=d.token_symbol||d.contract_address||"this token";return g(p("sendTokenNotInWallet",{symbol:e}),"bot",n.id),void I(!1)}if(u&&!s&&d.contract_address)try{const e=await So({address:d.contract_address,chain:J});if(e?.success&&e?.data){const n=e.data;s={symbol:n.symbol,name:n.name,balance:"0",balanceFormatted:"0",usdPrice:n.usd_price,decimals:n.decimals,logo:n.logo,contractAddress:d.contract_address},d={...d,decimals:String(n.decimals)}}}catch(a){}if(f&&P?.address)try{const e=await xo({address:P.address,chain:J});if(e?.success&&e?.data?.result){const n=e.data.result.find(e=>e.native_token);if(n){let e=n.balance_formatted,t=n.balance;try{const o=new vo(n.balance),a="0x"+BigInt(o.toFixed(0)).toString(16),i=await Xo({from:P.address,to:P.address,data:"0x",value:a,chainId:q,rpcUrl:G});if(i.isGreaterThan(0)){const a=o.minus(i);a.isGreaterThan(0)?(t=a.toFixed(0),e=vo(ge(BigInt(a.toFixed(0)),n.decimals)).toFixed()):(t="0",e="0")}}catch(r){}s={symbol:n.symbol,name:n.name,balance:t,balanceFormatted:e,usdValue:n.usd_value,usdPrice:n.usd_price,decimals:n.decimals,logo:n.logo||n.thumbnail,contractAddress:Vt}}else{const e=await So({address:Vt,chain:J});if(e?.success&&e?.data){const n=e.data;s={symbol:n.symbol,name:n.name,balance:"0",balanceFormatted:"0",usdValue:0,usdPrice:n.usd_price,decimals:n.decimals,logo:n.logo||n.thumbnail,contractAddress:Vt}}}}}catch(a){}if(m){try{const e=await async function(e){const{address:n,chain:t="base"}=e;if(!n)throw new Error("Contract address is required");try{return{success:!0,data:(await Io.get(`api/moralis/proxy/nft/${encodeURIComponent(n)}/metadata`,{query:{chain:t}})).data}}catch(o){return{success:!1,error:o instanceof Error?o.message:"Unknown error"}}}({address:d.contract_address,chain:J});if(e?.success&&e?.data){const n=e.data;n.contract_type&&(d={...d,token_standard:n.contract_type}),!d.nft_name&&n.name&&(d={...d,nft_name:n.name})}}catch(a){}if(P?.address)try{const e=await No({address:P.address,chain:J,limit:100,exclude_spam:!1});if(e?.success&&e?.data?.result){const t=e.data.result.find(e=>e.token_address.toLowerCase()===d.contract_address.toLowerCase()&&e.token_id===d.token_id);if(!t){const e=d.nft_name||`#${d.token_id||d.contract_address}`;return g(p("nftNotFoundInWallet",{name:e}),"bot",n.id),void I(!1)}{d={...d,amount:"1",maxAmount:t.amount||"1"};const e=t.normalized_metadata?.image||t.media?.original_media_url||"";c={name:t.normalized_metadata?.name||t.name||d.nft_name||`#${t.token_id}`,image:e||void 0,tokenId:t.token_id,contractAddress:t.token_address,tokenStandard:t.contract_type||d.token_standard||void 0}}}}catch(a){}}if(d.amount&&s?.balanceFormatted&&("send_token"===l.action||"send_native"===l.action)&&(d.amount=ia(d.amount,s.balanceFormatted,s.usdPrice)),i){const e=l.message||"Please review and complete the form below.";g(e,"bot",n.id,void 0,{action:l.action,parameters:d,status:"pending",tokenInfo:s,nftInfo:c})}else g(l.message||e,"bot",n.id)}else g(p("sendNftViaWebsite",{link:aa}),"bot");else try{const e=await xo({address:P.address,chain:J});if(e?.success&&e?.data?.result&&e.data.result.length>0){g(h("sendTokenChoose"),"bot",n.id),I(!0),await Lt(500);const t=e.data.result.map(e=>({id:`send-select-${e.token_address}`,text:`${e.name}: ${e.balance_formatted} ${e.symbol} ($${vo(e?.usd_value||0).decimalPlaces(2).toFixed()||"0"})`,value:`Send ${e.name} (${e.symbol})`,action:"suggested_action",fullWidth:!0}));await Lt(500),I(!1),g(p("walletBalanceSpendable",{chain:H?.name||"this chain"}),"bot",void 0,t)}else I(!1),g(p("walletNoTokensFound",{chain:H?.name||"this chain"}),"bot")}catch(a){I(!1),g(h("walletFetchError"),"bot")}else if(l&&"chat"===l.action){const t=l.token_mentions||[],o=l.suggested_actions||[],a=[];t.length>0&&t.forEach(e=>{a.push({id:`buy-${e.symbol}`,text:`💰 Buy ${e.symbol}`,value:p("buttonBuySymbol",{symbol:e.symbol}),action:"click_buy_item_token_button",extraData:{tokenAddress:e.contract_address||"",symbol:e.symbol,decimals:e.decimals||18},fullWidth:!0})}),o.length>0&&o.forEach((e,n)=>{a.push({id:`suggested-${n}-${e.label}`,text:e.label,value:e.prompt,action:"suggested_action",fullWidth:!0})}),a.length>0?g(l.message||e,"bot",n.id,a):g(l.message||e,"bot",n.id)}else g(e,"bot",n.id)}else g(h("errorProcessingRequest"),"bot",n.id)}catch(o){g(h("errorProcessingRequest"),"bot",n.id)}var t;I(!1),await Lt(50),ta.isDesktop&&U.current?.focus()},[C,E,b,g,N,P?.address,H?.name,H?.nativeCurrency?.symbol,H?.tokenTrendingDefault,q,Y,J,V,K,ee,ne,te,j,G,h,p]);i(()=>{F.current&&C===F.current&&(F.current=null,re())},[C,re]);const se=r(async(e,n,t)=>{try{if(S(!1),y(t,"submitted"),"swap_token"===e){let e=18;if(n.token_in&&n.token_in!==Vt)try{const t=await Bo.getTokensDetails([n.token_in],Y);t?.data?.[0]&&(e=t.data[0].decimals||18)}catch(o){}const i=qt(n.amount||"0",e).toString(),r=await Do({chainId:q,tokenIn:n.token_in||"",tokenInAmount:i,tokenOut:n.token_out||"",tokenOutRecipient:P?.address||"",slippage:"auto",accesstoken:"d6c45897b8f6"});if(r.success&&r.data){const e=r.data,o=e.tokenIn,s=e.tokenOut,c=vo(ge(BigInt(o.amount||0),o.decimals)).decimalPlaces(6).toFormat(),l=vo(ge(BigInt(s.amount||0),s.decimals)).decimalPlaces(6).toFormat(),d=!n.token_in||n.token_in===Vt;let u=!1;if(!d&&P?.address&&e.tx?.to)try{const t=await zo({tokenAddress:n.token_in,ownerAddress:P.address,spenderAddress:e.tx.to,chainId:q,rpcUrl:G});u=vo(t.toString()).isLessThan(i)}catch(a){}const f=e.estimatedTransactionFee?.total?vo(e.estimatedTransactionFee.total):vo(0);let m=vo(0);if(u&&P?.address)try{const t=Qo({tokenAddress:n.token_in,spenderAddress:e.tx?.to||"",fromAddress:P.address,chainId:q,amount:i});m=await Xo({from:P.address,to:t.to,data:t.data,chainId:q,rpcUrl:G})}catch(a){}const w=f.plus(m),b=H?.nativeCurrency?.symbol||"native";let A="",k=!1;if(P?.address&&w.isGreaterThan(0))try{const e=await jo({address:P.address,chainId:q,rpcUrl:G});if(e.isLessThan(w)){k=!0;const n=vo(ge(BigInt(e.toFixed(0)),18)).decimalPlaces(6).toFormat(),t=vo(ge(BigInt(w.toFixed(0)),18)).decimalPlaces(6).toFormat();A=p("swapFeeWarning",{symbol:b,balance:n,needed:t})}}catch(a){}const v=`From: ${c} ${o.symbol}\n⬇️\nTo: ${l} ${s.symbol}\n\n`+A+"\n";if(k)y(t,"pending"),g(v,"bot");else if(u){const a=[{id:"approve-swap-actionform",text:p("swapApproveButton",{symbol:o.symbol}),value:p("swapApproveValue",{symbol:o.symbol}),action:"approve_for_swap",extraData:{tokenAddress:n.token_in,spenderAddress:e.tx.to,tokenSymbol:o.symbol,amountInWei:i,tx:e.tx},fullWidth:!0}];y(t,"success"),g(v+p("swapApprovalRequired",{symbol:o.symbol}),"bot",void 0,a)}else{const n=[{id:"confirm-swap-actionform",text:h("swapConfirmYes"),value:h("swapConfirmValue"),action:"confirm_swap",extraData:{tx:e.tx}}];y(t,"success"),g(v+h("swapReadyToProceed"),"bot",void 0,n)}}else y(t,"pending"),g(p("swapEstimationError",{error:r.errorMessage||r.error||"Unknown error"}),"bot")}else{const o=function(e){const{action:n,parameters:t,fromAddress:o,chainId:a}=e;switch(n){case"send_native":return function(e,n,t){const{to_address:o,amount:a}=e;if(!o)throw new Error("Recipient address is required");if(!a)throw new Error("Amount is required");return{from:n,to:o,data:"0x",value:qt(a,18).toString(),chainId:t,description:`Send ${a} native token to ${o}`}}(t,o,a);case"send_token":return function(e,n,t){const{contract_address:o,to_address:a,amount:i,decimals:r,token_symbol:s}=e;if(!o)throw new Error("Token contract address is required");if(!a)throw new Error("Recipient address is required");if(!i)throw new Error("Amount is required");const c=qt(i,parseInt(r)||18);return{from:n,to:o,data:Dt({abi:Yo,functionName:"transfer",args:[a,c]}),value:"0",chainId:t,description:`Send ${i} ${s||"tokens"} to ${a}`}}(t,o,a);case"approve_token":return function(e,n,t){const{contract_address:o,spender_address:a,amount:i,token_symbol:r}=e;if(!o)throw new Error("Token contract address is required");if(!a)throw new Error("Spender address is required");const s=i&&""!==i?.trim()?qt(i,18):ie;return{from:n,to:o,data:Dt({abi:Yo,functionName:"approve",args:[a,s]}),value:"0",chainId:t,description:`Approve ${i||"unlimited"} ${r||"tokens"} for ${a}`}}(t,o,a);case"wrap_native":return function(e,n,t){const{amount:o}=e;if(!o)throw new Error("Amount is required");const a=Ho[t];if(!a)throw new Error(`WETH not supported on chain ${t}`);const i=qt(o,18).toString();return{from:n,to:a,data:Dt({abi:Jo,functionName:"deposit"}),value:i,chainId:t,description:`Wrap ${o} native token`}}(t,o,a);case"unwrap_native":return function(e,n,t){const{amount:o}=e;if(!o)throw new Error("Amount is required");const a=Ho[t];if(!a)throw new Error(`WETH not supported on chain ${t}`);const i=qt(o,18);return{from:n,to:a,data:Dt({abi:Jo,functionName:"withdraw",args:[i]}),value:"0",chainId:t,description:`Unwrap ${o} WETH`}}(t,o,a);case"send_nft":return function(e,n,t){const{contract_address:o,token_id:a,to_address:i,token_standard:r,amount:s,nft_name:c}=e;if(!o)throw new Error("NFT contract address is required");if(!a)throw new Error("Token ID is required");if(!i)throw new Error("Recipient address is required");const l=(r||"ERC721").toUpperCase(),d=BigInt(a);let u,f;if("ERC1155"===l){const e=BigInt(s||"1");u=Dt({abi:Vo,functionName:"safeTransferFrom",args:[n,i,d,e,"0x"]}),f=`Send ${e>1n?e.toString()+"x ":""}${c||"NFT"} (ERC1155 #${a}) to ${i}`}else u=Dt({abi:qo,functionName:"safeTransferFrom",args:[n,i,d]}),f=`Send ${c||"NFT"} (ERC721 #${a}) to ${i}`;return{from:n,to:o,data:u,value:"0",chainId:t,description:f}}(t,o,a);default:throw new Error(`Action "${n}" does not produce a transaction`)}}({action:e,parameters:n,fromAddress:P?.address||"",chainId:q||1}),a={from:o.from,to:o.to,data:o.data,value:o.value,chainId:o.chainId};if(("send_token"===e||"send_native"===e||"send_nft"===e)&&P?.address)try{const e=H?.nativeCurrency?.symbol||"native",n=await Xo({from:o.from,to:o.to,data:o.data,value:o.value&&"0"!==o.value?`0x${BigInt(o.value).toString(16)}`:void 0,chainId:q,rpcUrl:G});if(n.isGreaterThan(0)){const o=await jo({address:P.address,chainId:q,rpcUrl:G});if(o.isLessThan(n)){const a=vo(ge(BigInt(o.toFixed(0)),18)).decimalPlaces(6).toFormat(),i=vo(ge(BigInt(n.toFixed(0)),18)).decimalPlaces(6).toFormat();return y(t,"pending"),void g(p("txInsufficientGas",{symbol:e,balance:a,fee:i}),"bot")}}}catch(i){}const s=k(t);if(l){I(!1);const e=await l(a);if("success"===e.status&&e.transactionHash){const n=H?.blockExplorers?.default?.url,o=n?`\n[View on Explorer](${n}/tx/${e.transactionHash})`:`\nTx: ${e.transactionHash}`;try{await Lt(2e3),"success"===(await Go({transactionHash:e.transactionHash,chainId:q||1,rpcUrl:G})).status?(y(t,"success"),A(t,s?.text+"\n"+o)):(y(t,"pending"),g(h("txReverted")+"\n"+o,"bot"))}catch(r){y(t,"success"),g(h("txTimeout")+"\n"+o,"bot")}}else if("success"===e.status)y(t,"success");else{y(t,"pending");const n=e.error?`\nError: ${e.error}`:"";g(h("txFailed")+n,"bot")}}else y(t,"pending"),g(h("txNoHandler"),"bot")}}catch(s){y(t,"pending"),g(p("txError",{message:s instanceof Error?s.message:"Unknown error"}),"bot")}},[y,q,P?.address,Y,H?.nativeCurrency?.symbol,H?.blockExplorers?.default?.url,G,p,g,h,k,l,A]),ce=r(e=>{v([e])},[v]),[le,de]=a({}),ue=r(async(e,n,t)=>{de(e=>({...e,[t]:!0}));try{await se(e,n,t)}finally{de(e=>({...e,[t]:!1}))}},[se]),fe=r(e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),re())},[re]),me=r(()=>{const e=window.getSelection();e&&e.toString().length>0||s()},[s]);return o?/* @__PURE__ */e("div",{className:"chat-modal-overlay"+("bottom-left"===f?" chat-modal-overlay--left":""),onClick:me,role:"dialog","aria-modal":"true","aria-labelledby":"chat-modal-title",children:/* @__PURE__ */t("div",{className:"chat-modal",style:m,onClick:e=>e.stopPropagation(),children:[
30
30
  /* @__PURE__ */t("div",{className:"chat-modal-header",children:[
31
31
  /* @__PURE__ */t("div",{className:"chat-modal-header-left",children:[
32
32
  /* @__PURE__ */e("div",{className:"keyring-logo",children:/* @__PURE__ */e("img",{src:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAx8SURBVHgB7VprbFzFFT5n9kmoil0JiUqVsuYX/7BRSeL+aOyKivKjxYYEmpbWNlQpUYvsQAtBVPHdoBYFodgWIiAK8ppWysOVbFrRh0qxUyE5BlQ7/VEqVYo3P6qq6iMbpYTEu3dOz7zuY72Jr51NIrU59u597NyZ+ea8zx2A63Sd/qcI4QoQTfW0QC3fDrLWpS4BUxUAeQwfmFyEa0xNB0xHtw9yrx7DbAlH4WGI1FkZBHq47egEXCNqGmCa3NbF3Q0z0K7IXbLD1I+zBCh24/Yjb8JVpssGTIe+WoCUP8TYbufemKvYzkdSghwcTUsKgQfnJfCrRdwxXYarRM0X6XHW3w3Ze1ln+xlTV4MWFMo4mkUBKkK6NoG9Vx74ugHfNjNXyJ/nk/P5ymJvR6VRGzpyfw+AGOFRCoF4o8BA0s0MrBQg6zdccf1eE+CWhYWWDedrg7mqP5StYUtOAuVqgHy+mPFpOi/lxK97O8v1z7Eh6+fDMH8KcdFuOCV+nnqvlEVPDLhlbq6QQpzJ+lhgkMBgQR2zPlBegfYB8vzJkvBguTYxvSMOnA71FECkPcbal0C3FZUgw/rdZDFPDPjG9+eXGGQhr0DWCHI+8keB5nMpiO9hzoGuQZnPvTce2rxCPDXwVHaEdfzeOKcvwnlkN7b9aBGaRIkAZxbm+pmz43kGmVXcVUB9ZHE2INUnq6/1Aqh7xB8+4lLmAtx3cOemFeJJh1jMBYu51m9YiTcqBUSzPPBAM7idCHBu4b2ZtISteQaTrTmuohZpw2Ut2vqYl0YC1OJkagZ43qdS2qfi/l0N9Hty2zBIZItOGxtwmMI5sm77y92X68JEkkYSZTsShZPRXoX/lb0NLC5pruhLFGQYph/hU+wTIE7ufXF+uL5v3P6zIshqN59FxZ+Mu4oyhFgVMu9w2FqAy6DVObwwV8iAWDJia0RZc5qPWZ85qa20E/PQgLnrXPx3pePlrEx5jz/+2Qb6HRHzMByNtlDLeAo+qnbgwHQF1kEJOJxWg+uRLb/MBTNAAJ1hLntIsnvPhd9M3+X/GW6ms6DbE0Cgg+Z50lEGMRjplw4+P7/wsjdXiI6EOyZLmtvEMTdJCjDGQW+EDekpWCclAFzTINWkyeiUA4TLgAMf3L25+O6XO2e/6P+psrv6Wyhe+AV8vvoXLfNBe6sO+iHDOCIJt2czqZMT++JirnVUpljExSmjDVEhVJGZilGwiw4/MATroEQ67CaNNj7W+ow0++Fdm6ejs1Hwbqb/wM7qu7D//M/pM/K0XijLYQva2SDugfSVd8SbH4EY6MNsoEQIOkZ2BQSNcEDTDlcEsOaukVIbBoIEjLkaGUzGtPqUPId7Pn6HUfkPs3ieskbIMc2KupEVATg49czxcagHzREXtzgT3lSTiIWlI7BGSgZYcRcwIl0KtTwT6yiMkK3/NJcvPtJZOvDtLW1Qk/sadm04jQy671d76kCr8JI4t44Oq39wiwdddEilpclpDRx2+uuAiZioSQMSjJ5RnUsBeO6xTo9Bt3FXJQqEhRtR4ILUVf/vnnw/rtMPTI7xYSa8Q3EuC1jh6i5FSay0HdkurlllUt75Yk8ogcAGHs/b3VneM7RlQBDewY3KtiMFF8kuEErp/f6J+Z7Yg37qYf61YhamLjhRBuzo9q2QkJJbaTM5t7Qo6zisOkK3FhBofEPa/eSmxe/s2dLGKD3UeonhA9yFkDS+MLQQlIi0PksajVi8wPIZoxAR+1UoGYetZVZ8Iyt+ogGHnfKaiawe0zzyg81FIeXDZFx0AJ1Pb/LpQtwgZWtjmstGGay7ChZ1qy48JKBkHLZdK+MCgUjXParWAiEwwUnTsK97naUU4JBxr0Zm9YpJ7PvjrvcCUeXEgSMr5rIR/EgRwXL7hnR/kvGS+2EAF2I1JGW0iMCFWGSCDKIkHW/bt2mMHxw1AbhTZv4T0os1TNfG7FQihg6M9RZ4OySgRICtycVgMpdioIlPgpYfjzxVgATkZ84VeZHOxFSfsOvDR+e63KXmskoVYxwOKJHhSgQYyfxT6Ak5MoxbJYH1VoqM+1axeALq9borKcJRhCBU1y5akBis6/ZNMxLGfTJAWxI9Tu6WzOwxKMU14DKC019yXkZN615ISNnl7BjFNEclKLB1oT+02Jx0l2Ijk3Vs6iQPzQBcKwenNuvR51KuaEmBO8IgWeDT/tMjXiIL2j3aURGIs0gmXTF9QGtLdjlYNCPWnE2FwQoG1ZJUZuNqYyQAnK9o3VXDS7qEAcYTYJ2SgaxFQn21ZCUmzmxIyhPOVpAr9BB11bU6FhT6zdjGe/i0qnNYHXBHRwXVikJgj6jhk0SLzjMqsGSttjEuYjAplzmeUUmJS69MYirrCvpCnDZjRhYfIZFHSGS0ONGfDS6CqAtjADgamuURy2jZqg4CXZxMLJU3jEMS8m1/EEQw6ruwFNVjKeMZlJ2QMzeXxpKA2CSfUGyzdS0bacEKvyelqUu5gE+n0BToYs/ZHx0YhnWQkt0MVAvhDSzHgJoTsjHSJSkR4Avi45Iu7RjdshYJu9pnFmJcznzjDY9/KJvChLPSrpCnhcM7u++lS4NOuembMFUbMB3EyNAgERZcj3DxN5QNKVmk1dHNlpGtJ7jUALQo1eTyYH1TkmKAgsmYqTtLp/wqR2ReZe9rJ09744WGYzmRtmEmOGtN1Bo2kgC21hPzx80SaUVp8IvBWpqP8sX97VN1XB54bZYXZ0hH1mBFO5Bycvfa6EJq6V/fPzx+emiqEBvIchgiObMZVMSS4BWkJtcskVZUubNzlqsSs3YShocSNqY3rORy9lsHx/i3op5naD0DmUMIE35f4B/+8d236sWcbIElEoNEsjMhG1hkbp7CVS31WpIHHtQvhr3b+Jpg+HNvvbeimJbbNer5EnqZqaccVONqMHhBbJeula+G/77r7aW/7TzW12BQwPq0RULYYdiueW7J0T87Ay6T02OTKdBU11S8xqzoxseen75h8Nk2Dlg8dOUrI+suL6IwdON6NWHplo/EXgiDG+PUsD6gsNPG0E7Y0lITAo96StOQmYmdjwFdEELMfKkBaEU3fm9vcVnKW3lWE7Ye4lyJM+LBRBlDGwRBloJhdVekIrN2Rfq61xPN1GFHf928+YTw6XErj5GMEQqc2yz1TM43dDutTz9d/uQzQ2zBBQMSZXefopmC+XZcs8GHju8oRZGWLowPtMPqTDOtdJROdm8Z5bGOOadvyz5ka5Deg4fml7750/m+Rs+2ervKrc8+0sYZez+ztxykgxYkRAomzkwrXfAx/grCHhL53iitC7CiPOa4SG5ibDsDF2moebI+QmlnaX7h0fHGYt763EMTHEx0M+Mi9epg/jpLdJZRg5Z+ua6L6EKZ81qtDKvQugEvdnMqV5XdqDabheEd2Hk75rSnpVh64tXj40+9vBJ46/4d5ZtHez2/Ktp4yhM6MHF5A5KLPAihPjEQZpRotsSeM8m743UDVrR4T2dZ8JtDVWO2t3TmEE/dQMlkP78fntn7UmP9/vQr95RveeWuAUrVbj2b47hdP+NKoLaQGZu1jMTRlrtEiTbBXBZgRccZdKZG3axis6YYhOFkbHJoiyQbhQTvudH5pQMHPmio34s35eFcBlrI1nf0UxGbFJCM5uQ2iANRggR02YAVzfZ2lt/+yiYFumhDZ8PnoKQL0UOBfH/8pf3zUz9+NizQTXkLLYipcfX+OBpoUFgKDQmjmZrWgDI+mGx/V1MAO/pl751F8Pn9Eck3LHtMgmXfJwcv1o3A96BIvfOTfcf/fWT4+JKoLZ9mdFstIFcjiufFjgjbQ1HmSM6vfgESUlMBK1L7sw5/rbNfVPEOdl2nzKSsDkoKQIf6ia18swDubbmlSAhlDVdKb3HQm1j1zh/deAzOVTvWstFlzX5srfTYq3P9WRLDWR826p0/1XCrU66m94lg3uwAIrUXxGyNUruEACO7g8qF1zerCEzt6hvXgFNiCO87cmKN02k+h+vpxZ2dJV8qSy73IdUvMOk6ClC4Syt4z2QbmIPN0o7c38eFugncPtm9HrC6J7iK5I3MFfKcGWVr2J9zXNX7uMDu+TIc15ytBbt+IIOyrXD3/gq/SoP17t5xdFUBO3rhhfmeDTUYYbCFnNmqqEQ5AGu3O2mxzlRp922vbhmFJtE1Aezo9R+qLY1imAEWAo5arud8qqRqtLvjYGcJmkjXFLCjo9677bnl9Nasj60swpSuyWOfgPxix2jHZYnvdbpO/wf0X652D+/dGV80AAAAAElFTkSuQmCC",alt:"Keyring Logo",width:40,height:40})}),