UNPKG

@safe-stars/components

Version:

React component library for buying Telegram Stars in Telegram Mini Apps via Safe Stars.

37 lines (34 loc) 18.9 kB
"use strict";const n=require("./index-CtZaCMo8.cjs"),y=require("./if-defined-MmHKu2JE.cjs");require("./index-BXulAD-4.cjs");require("./index-CKpCHYPu.cjs");const N={async getTokenList(){var s;const t=n.ChainController.state.activeCaipNetwork,o=await n.BlockchainApiController.fetchSwapTokens({chainId:t==null?void 0:t.caipNetworkId});return((s=o==null?void 0:o.tokens)==null?void 0:s.map(a=>({...a,eip2612:!1,quantity:{decimals:"0",numeric:"0"},price:0,value:0})))||[]},async fetchGasPrice(){var o,r;const t=n.ChainController.state.activeCaipNetwork;if(!t)return null;try{switch(t.chainNamespace){case"solana":const s=(r=await((o=n.ConnectionController)==null?void 0:o.estimateGas({chainNamespace:"solana"})))==null?void 0:r.toString();return{standard:s,fast:s,instant:s};case"eip155":default:return await n.BlockchainApiController.fetchGasPrice({chainId:t.caipNetworkId})}}catch{return null}},async fetchSwapAllowance({tokenAddress:t,userAddress:o,sourceTokenAmount:r,sourceTokenDecimals:s}){const a=await n.BlockchainApiController.fetchSwapAllowance({tokenAddress:t,userAddress:o});if(a!=null&&a.allowance&&r&&s){const c=n.ConnectionController.parseUnits(r,s)||0;return BigInt(a.allowance)>=c}return!1},async getMyTokensWithBalance(t){const o=n.AccountController.state.address,r=n.ChainController.state.activeCaipNetwork;if(!o||!r)return[];const a=(await n.BlockchainApiController.getBalance(o,r.caipNetworkId,t)).balances.filter(c=>c.quantity.decimals!=="0");return n.AccountController.setTokenBalance(a,n.ChainController.state.activeChain),this.mapBalancesToSwapTokens(a)},mapBalancesToSwapTokens(t){return(t==null?void 0:t.map(o=>({...o,address:o!=null&&o.address?o.address:n.ChainController.getActiveNetworkTokenAddress(),decimals:parseInt(o.quantity.decimals,10),logoUri:o.iconUrl,eip2612:!1})))||[]}},f={getGasPriceInEther(t,o){const r=o*t;return Number(r)/1e18},getGasPriceInUSD(t,o,r){const s=f.getGasPriceInEther(o,r);return n.NumberUtil.bigNumber(t).times(s).toNumber()},getPriceImpact({sourceTokenAmount:t,sourceTokenPriceInUSD:o,toTokenPriceInUSD:r,toTokenAmount:s}){const a=n.NumberUtil.bigNumber(t).times(o),c=n.NumberUtil.bigNumber(s).times(r);return a.minus(c).div(a).times(100).toNumber()},getMaxSlippage(t,o){const r=n.NumberUtil.bigNumber(t).div(100);return n.NumberUtil.multiply(o,r).toNumber()},getProviderFee(t,o=.0085){return n.NumberUtil.bigNumber(t).times(o).toString()},isInsufficientNetworkTokenForGas(t,o){const r=o||"0";return n.NumberUtil.bigNumber(t).eq(0)?!0:n.NumberUtil.bigNumber(n.NumberUtil.bigNumber(r)).gt(t)},isInsufficientSourceTokenForSwap(t,o,r){var c,u;const s=(u=(c=r==null?void 0:r.find(l=>l.address===o))==null?void 0:c.quantity)==null?void 0:u.numeric;return n.NumberUtil.bigNumber(s||"0").lt(t)},getToTokenAmount({sourceToken:t,toToken:o,sourceTokenPrice:r,toTokenPrice:s,sourceTokenAmount:a}){if(a==="0"||!t||!o)return"0";const c=t.decimals,u=r,l=o.decimals,k=s;if(k<=0)return"0";const d=n.NumberUtil.bigNumber(a).times(.0085),g=n.NumberUtil.bigNumber(a).minus(d).times(n.NumberUtil.bigNumber(10).pow(c)),w=n.NumberUtil.bigNumber(u).div(k),A=c-l;return g.times(w).div(n.NumberUtil.bigNumber(10).pow(A)).div(n.NumberUtil.bigNumber(10).pow(l)).toFixed(l).toString()}},D=15e4,x=6,T={initializing:!1,initialized:!1,loadingPrices:!1,loadingQuote:!1,loadingApprovalTransaction:!1,loadingBuildTransaction:!1,loadingTransaction:!1,fetchError:!1,approvalTransaction:void 0,swapTransaction:void 0,transactionError:void 0,sourceToken:void 0,sourceTokenAmount:"",sourceTokenPriceInUSD:0,toToken:void 0,toTokenAmount:"",toTokenPriceInUSD:0,networkPrice:"0",networkBalanceInUSD:"0",networkTokenSymbol:"",inputError:void 0,slippage:n.ConstantsUtil.CONVERT_SLIPPAGE_TOLERANCE,tokens:void 0,popularTokens:void 0,suggestedTokens:void 0,foundTokens:void 0,myTokensWithBalance:void 0,tokensPriceMap:{},gasFee:"0",gasPriceInUSD:0,priceImpact:void 0,maxSlippage:void 0,providerFee:void 0},e=n.proxy(T),b={state:e,subscribe(t){return n.subscribe(e,()=>t(e))},subscribeKey(t,o){return n.subscribeKey(e,t,o)},getParams(){var k,d,m,g,w,A,S,h;const t=n.ChainController.state.activeCaipAddress,o=n.ChainController.state.activeChain,r=n.CoreHelperUtil.getPlainAddress(t),s=n.ChainController.getActiveNetworkTokenAddress(),a=n.ConnectorController.getConnectorId(o);if(!r)throw new Error("No address found to swap the tokens from.");const c=!((k=e.toToken)!=null&&k.address)||!((d=e.toToken)!=null&&d.decimals),u=!((m=e.sourceToken)!=null&&m.address)||!((g=e.sourceToken)!=null&&g.decimals)||!n.NumberUtil.bigNumber(e.sourceTokenAmount).gt(0),l=!e.sourceTokenAmount;return{networkAddress:s,fromAddress:r,fromCaipAddress:t,sourceTokenAddress:(w=e.sourceToken)==null?void 0:w.address,toTokenAddress:(A=e.toToken)==null?void 0:A.address,toTokenAmount:e.toTokenAmount,toTokenDecimals:(S=e.toToken)==null?void 0:S.decimals,sourceTokenAmount:e.sourceTokenAmount,sourceTokenDecimals:(h=e.sourceToken)==null?void 0:h.decimals,invalidToToken:c,invalidSourceToken:u,invalidSourceTokenAmount:l,availableToSwap:t&&!c&&!u&&!l,isAuthConnector:a===n.ConstantsUtil$1.CONNECTOR_ID.AUTH}},setSourceToken(t){if(!t){e.sourceToken=t,e.sourceTokenAmount="",e.sourceTokenPriceInUSD=0;return}e.sourceToken=t,i.setTokenPrice(t.address,"sourceToken")},setSourceTokenAmount(t){e.sourceTokenAmount=t},setToToken(t){if(!t){e.toToken=t,e.toTokenAmount="",e.toTokenPriceInUSD=0;return}e.toToken=t,i.setTokenPrice(t.address,"toToken")},setToTokenAmount(t){e.toTokenAmount=t?n.NumberUtil.formatNumberToLocalString(t,x):""},async setTokenPrice(t,o){let r=e.tokensPriceMap[t]||0;r||(e.loadingPrices=!0,r=await i.getAddressPrice(t)),o==="sourceToken"?e.sourceTokenPriceInUSD=r:o==="toToken"&&(e.toTokenPriceInUSD=r),e.loadingPrices&&(e.loadingPrices=!1),i.getParams().availableToSwap&&i.swapTokens()},switchTokens(){if(e.initializing||!e.initialized)return;const t=e.toToken?{...e.toToken}:void 0,o=e.sourceToken?{...e.sourceToken}:void 0,r=t&&e.toTokenAmount===""?"1":e.toTokenAmount;i.setSourceToken(t),i.setToToken(o),i.setSourceTokenAmount(r),i.setToTokenAmount(""),i.swapTokens()},resetState(){e.myTokensWithBalance=T.myTokensWithBalance,e.tokensPriceMap=T.tokensPriceMap,e.initialized=T.initialized,e.sourceToken=T.sourceToken,e.sourceTokenAmount=T.sourceTokenAmount,e.sourceTokenPriceInUSD=T.sourceTokenPriceInUSD,e.toToken=T.toToken,e.toTokenAmount=T.toTokenAmount,e.toTokenPriceInUSD=T.toTokenPriceInUSD,e.networkPrice=T.networkPrice,e.networkTokenSymbol=T.networkTokenSymbol,e.networkBalanceInUSD=T.networkBalanceInUSD,e.inputError=T.inputError,e.myTokensWithBalance=T.myTokensWithBalance},resetValues(){var r;const{networkAddress:t}=i.getParams(),o=(r=e.tokens)==null?void 0:r.find(s=>s.address===t);i.setSourceToken(o),i.setToToken(void 0)},getApprovalLoadingState(){return e.loadingApprovalTransaction},clearError(){e.transactionError=void 0},async initializeState(){if(!e.initializing){if(e.initializing=!0,!e.initialized)try{await i.fetchTokens(),e.initialized=!0}catch{e.initialized=!1,n.SnackController.showError("Failed to initialize swap"),n.RouterController.goBack()}e.initializing=!1}},async fetchTokens(){var r;const{networkAddress:t}=i.getParams();await i.getTokenList(),await i.getNetworkTokenPrice(),await i.getMyTokensWithBalance();const o=(r=e.tokens)==null?void 0:r.find(s=>s.address===t);o&&(e.networkTokenSymbol=o.symbol,i.setSourceToken(o),i.setSourceTokenAmount("1"))},async getTokenList(){const t=await N.getTokenList();e.tokens=t,e.popularTokens=t.sort((o,r)=>o.symbol<r.symbol?-1:o.symbol>r.symbol?1:0),e.suggestedTokens=t.filter(o=>!!n.ConstantsUtil.SWAP_SUGGESTED_TOKENS.includes(o.symbol),{})},async getAddressPrice(t){var k,d;const o=e.tokensPriceMap[t];if(o)return o;const r=await n.BlockchainApiController.fetchTokenPrice({addresses:[t]}),s=(r==null?void 0:r.fungibles)||[],a=[...e.tokens||[],...e.myTokensWithBalance||[]],c=(k=a==null?void 0:a.find(m=>m.address===t))==null?void 0:k.symbol,u=((d=s.find(m=>m.symbol.toLowerCase()===(c==null?void 0:c.toLowerCase())))==null?void 0:d.price)||0,l=parseFloat(u.toString());return e.tokensPriceMap[t]=l,l},async getNetworkTokenPrice(){var a;const{networkAddress:t}=i.getParams(),r=(a=(await n.BlockchainApiController.fetchTokenPrice({addresses:[t]}).catch(()=>(n.SnackController.showError("Failed to fetch network token price"),{fungibles:[]}))).fungibles)==null?void 0:a[0],s=(r==null?void 0:r.price.toString())||"0";e.tokensPriceMap[t]=parseFloat(s),e.networkTokenSymbol=(r==null?void 0:r.symbol)||"",e.networkPrice=s},async getMyTokensWithBalance(t){const o=await n.SendApiUtil.getMyTokensWithBalance(t),r=n.SendApiUtil.mapBalancesToSwapTokens(o);r&&(await i.getInitialGasPrice(),i.setBalances(r))},setBalances(t){const{networkAddress:o}=i.getParams(),r=n.ChainController.state.activeCaipNetwork;if(!r)return;const s=t.find(a=>a.address===o);t.forEach(a=>{e.tokensPriceMap[a.address]=a.price||0}),e.myTokensWithBalance=t.filter(a=>a.address.startsWith(r.caipNetworkId)),e.networkBalanceInUSD=s?n.NumberUtil.multiply(s.quantity.numeric,s.price).toString():"0"},async getInitialGasPrice(){var o,r;const t=await N.fetchGasPrice();if(!t)return{gasPrice:null,gasPriceInUSD:null};switch((r=(o=n.ChainController.state)==null?void 0:o.activeCaipNetwork)==null?void 0:r.chainNamespace){case"solana":return e.gasFee=t.standard??"0",e.gasPriceInUSD=n.NumberUtil.multiply(t.standard,e.networkPrice).div(1e9).toNumber(),{gasPrice:BigInt(e.gasFee),gasPriceInUSD:Number(e.gasPriceInUSD)};case"eip155":default:const s=t.standard??"0",a=BigInt(s),c=BigInt(D),u=f.getGasPriceInUSD(e.networkPrice,c,a);return e.gasFee=s,e.gasPriceInUSD=u,{gasPrice:a,gasPriceInUSD:u}}},async swapTokens(){var c,u;const t=n.AccountController.state.address,o=e.sourceToken,r=e.toToken,s=n.NumberUtil.bigNumber(e.sourceTokenAmount).gt(0);if(s||i.setToTokenAmount(""),!r||!o||e.loadingPrices||!s)return;e.loadingQuote=!0;const a=n.NumberUtil.bigNumber(e.sourceTokenAmount).times(10**o.decimals).round(0);try{const l=await n.BlockchainApiController.fetchSwapQuote({userAddress:t,from:o.address,to:r.address,gasPrice:e.gasFee,amount:a.toString()});e.loadingQuote=!1;const k=(u=(c=l==null?void 0:l.quotes)==null?void 0:c[0])==null?void 0:u.toAmount;if(!k){n.AlertController.open({shortMessage:"Incorrect amount",longMessage:"Please enter a valid amount"},"error");return}const d=n.NumberUtil.bigNumber(k).div(10**r.decimals).toString();i.setToTokenAmount(d),i.hasInsufficientToken(e.sourceTokenAmount,o.address)?e.inputError="Insufficient balance":(e.inputError=void 0,i.setTransactionDetails())}catch{e.loadingQuote=!1,e.inputError="Insufficient balance"}},async getTransaction(){const{fromCaipAddress:t,availableToSwap:o}=i.getParams(),r=e.sourceToken,s=e.toToken;if(!(!t||!o||!r||!s||e.loadingQuote))try{e.loadingBuildTransaction=!0;const a=await N.fetchSwapAllowance({userAddress:t,tokenAddress:r.address,sourceTokenAmount:e.sourceTokenAmount,sourceTokenDecimals:r.decimals});let c;return a?c=await i.createSwapTransaction():c=await i.createAllowanceTransaction(),e.loadingBuildTransaction=!1,e.fetchError=!1,c}catch{n.RouterController.goBack(),n.SnackController.showError("Failed to check allowance"),e.loadingBuildTransaction=!1,e.approvalTransaction=void 0,e.swapTransaction=void 0,e.fetchError=!0;return}},async createAllowanceTransaction(){const{fromCaipAddress:t,sourceTokenAddress:o,toTokenAddress:r}=i.getParams();if(!(!t||!r)){if(!o)throw new Error("createAllowanceTransaction - No source token address found.");try{const s=await n.BlockchainApiController.generateApproveCalldata({from:o,to:r,userAddress:t}),a={data:s.tx.data,to:n.CoreHelperUtil.getPlainAddress(s.tx.from),gasPrice:BigInt(s.tx.eip155.gasPrice),value:BigInt(s.tx.value),toAmount:e.toTokenAmount};return e.swapTransaction=void 0,e.approvalTransaction={data:a.data,to:a.to,gasPrice:a.gasPrice,value:a.value,toAmount:a.toAmount},{data:a.data,to:a.to,gasPrice:a.gasPrice,value:a.value,toAmount:a.toAmount}}catch{n.RouterController.goBack(),n.SnackController.showError("Failed to create approval transaction"),e.approvalTransaction=void 0,e.swapTransaction=void 0,e.fetchError=!0;return}}},async createSwapTransaction(){var u;const{networkAddress:t,fromCaipAddress:o,sourceTokenAmount:r}=i.getParams(),s=e.sourceToken,a=e.toToken;if(!o||!r||!s||!a)return;const c=(u=n.ConnectionController.parseUnits(r,s.decimals))==null?void 0:u.toString();try{const l=await n.BlockchainApiController.generateSwapCalldata({userAddress:o,from:s.address,to:a.address,amount:c,disableEstimate:!0}),k=s.address===t,d=BigInt(l.tx.eip155.gas),m=BigInt(l.tx.eip155.gasPrice),g={data:l.tx.data,to:n.CoreHelperUtil.getPlainAddress(l.tx.to),gas:d,gasPrice:m,value:BigInt(k?c??"0":"0"),toAmount:e.toTokenAmount};return e.gasPriceInUSD=f.getGasPriceInUSD(e.networkPrice,d,m),e.approvalTransaction=void 0,e.swapTransaction=g,g}catch{n.RouterController.goBack(),n.SnackController.showError("Failed to create transaction"),e.approvalTransaction=void 0,e.swapTransaction=void 0,e.fetchError=!0;return}},async sendTransactionForApproval(t){var a,c,u,l;const{fromAddress:o,isAuthConnector:r}=i.getParams();e.loadingApprovalTransaction=!0;const s="Approve limit increase in your wallet";r?n.RouterController.pushTransactionStack({view:null,goBack:!0,onSuccess(){n.SnackController.showLoading(s)}}):n.SnackController.showLoading(s);try{await n.ConnectionController.sendTransaction({address:o,to:t.to,data:t.data,value:t.value,chainNamespace:"eip155"}),await i.swapTokens(),await i.getTransaction(),e.approvalTransaction=void 0,e.loadingApprovalTransaction=!1}catch(k){const d=k;e.transactionError=d==null?void 0:d.shortMessage,e.loadingApprovalTransaction=!1,n.SnackController.showError((d==null?void 0:d.shortMessage)||"Transaction error"),n.EventsController.sendEvent({type:"track",event:"SWAP_APPROVAL_ERROR",properties:{message:(d==null?void 0:d.shortMessage)||(d==null?void 0:d.message)||"Unknown",network:((a=n.ChainController.state.activeCaipNetwork)==null?void 0:a.caipNetworkId)||"",swapFromToken:((c=i.state.sourceToken)==null?void 0:c.symbol)||"",swapToToken:((u=i.state.toToken)==null?void 0:u.symbol)||"",swapFromAmount:i.state.sourceTokenAmount||"",swapToAmount:i.state.toTokenAmount||"",isSmartAccount:((l=n.AccountController.state.preferredAccountTypes)==null?void 0:l.eip155)===n.W3mFrameRpcConstants.ACCOUNT_TYPES.SMART_ACCOUNT}})}},async sendTransactionForSwap(t){var u,l,k,d,m,g,w,A,S,h,P,U,B,E;if(!t)return;const{fromAddress:o,toTokenAmount:r,isAuthConnector:s}=i.getParams();e.loadingTransaction=!0;const a=`Swapping ${(u=e.sourceToken)==null?void 0:u.symbol} to ${n.NumberUtil.formatNumberToLocalString(r,3)} ${(l=e.toToken)==null?void 0:l.symbol}`,c=`Swapped ${(k=e.sourceToken)==null?void 0:k.symbol} to ${n.NumberUtil.formatNumberToLocalString(r,3)} ${(d=e.toToken)==null?void 0:d.symbol}`;s?n.RouterController.pushTransactionStack({view:"Account",goBack:!1,onSuccess(){n.SnackController.showLoading(a),b.resetState()}}):n.SnackController.showLoading("Confirm transaction in your wallet");try{const I=[(m=e.sourceToken)==null?void 0:m.address,(g=e.toToken)==null?void 0:g.address].join(","),p=await n.ConnectionController.sendTransaction({address:o,to:t.to,data:t.data,value:t.value,chainNamespace:"eip155"});return e.loadingTransaction=!1,n.SnackController.showSuccess(c),n.EventsController.sendEvent({type:"track",event:"SWAP_SUCCESS",properties:{network:((w=n.ChainController.state.activeCaipNetwork)==null?void 0:w.caipNetworkId)||"",swapFromToken:((A=i.state.sourceToken)==null?void 0:A.symbol)||"",swapToToken:((S=i.state.toToken)==null?void 0:S.symbol)||"",swapFromAmount:i.state.sourceTokenAmount||"",swapToAmount:i.state.toTokenAmount||"",isSmartAccount:((h=n.AccountController.state.preferredAccountTypes)==null?void 0:h.eip155)===n.W3mFrameRpcConstants.ACCOUNT_TYPES.SMART_ACCOUNT}}),b.resetState(),s||n.RouterController.replace("Account"),b.getMyTokensWithBalance(I),p}catch(I){const p=I;e.transactionError=p==null?void 0:p.shortMessage,e.loadingTransaction=!1,n.SnackController.showError((p==null?void 0:p.shortMessage)||"Transaction error"),n.EventsController.sendEvent({type:"track",event:"SWAP_ERROR",properties:{message:(p==null?void 0:p.shortMessage)||(p==null?void 0:p.message)||"Unknown",network:((P=n.ChainController.state.activeCaipNetwork)==null?void 0:P.caipNetworkId)||"",swapFromToken:((U=i.state.sourceToken)==null?void 0:U.symbol)||"",swapToToken:((B=i.state.toToken)==null?void 0:B.symbol)||"",swapFromAmount:i.state.sourceTokenAmount||"",swapToAmount:i.state.toTokenAmount||"",isSmartAccount:((E=n.AccountController.state.preferredAccountTypes)==null?void 0:E.eip155)===n.W3mFrameRpcConstants.ACCOUNT_TYPES.SMART_ACCOUNT}});return}},hasInsufficientToken(t,o){return f.isInsufficientSourceTokenForSwap(t,o,e.myTokensWithBalance)},setTransactionDetails(){const{toTokenAddress:t,toTokenDecimals:o}=i.getParams();!t||!o||(e.gasPriceInUSD=f.getGasPriceInUSD(e.networkPrice,BigInt(e.gasFee),BigInt(D)),e.priceImpact=f.getPriceImpact({sourceTokenAmount:e.sourceTokenAmount,sourceTokenPriceInUSD:e.sourceTokenPriceInUSD,toTokenPriceInUSD:e.toTokenPriceInUSD,toTokenAmount:e.toTokenAmount}),e.maxSlippage=f.getMaxSlippage(e.slippage,e.toTokenAmount),e.providerFee=f.getProviderFee(e.sourceTokenAmount))}},i=n.withErrorBoundary(b),F=n.i` :host { display: block; } :host > button { gap: var(--wui-spacing-xxs); padding: var(--wui-spacing-xs); padding-right: var(--wui-spacing-1xs); height: 40px; border-radius: var(--wui-border-radius-l); background: var(--wui-color-gray-glass-002); border-width: 0px; box-shadow: inset 0 0 0 1px var(--wui-color-gray-glass-002); } :host > button wui-image { width: 24px; height: 24px; border-radius: var(--wui-border-radius-s); box-shadow: inset 0 0 0 1px var(--wui-color-gray-glass-010); } `;var v=function(t,o,r,s){var a=arguments.length,c=a<3?o:s===null?s=Object.getOwnPropertyDescriptor(o,r):s,u;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")c=Reflect.decorate(t,o,r,s);else for(var l=t.length-1;l>=0;l--)(u=t[l])&&(c=(a<3?u(c):a>3?u(o,r,c):u(o,r))||c);return a>3&&c&&Object.defineProperty(o,r,c),c};let C=class extends n.i$1{constructor(){super(...arguments),this.text=""}render(){return n.x` <button> ${this.tokenTemplate()} <wui-text variant="paragraph-600" color="fg-100">${this.text}</wui-text> </button> `}tokenTemplate(){return this.imageSrc?n.x`<wui-image src=${this.imageSrc}></wui-image>`:n.x` <wui-icon-box size="sm" iconColor="fg-200" backgroundColor="fg-300" icon="networkPlaceholder" ></wui-icon-box> `}};C.styles=[n.resetStyles,n.elementStyles,F];v([y.n()],C.prototype,"imageSrc",void 0);v([y.n()],C.prototype,"text",void 0);C=v([y.customElement("wui-token-button")],C);exports.SwapController=i; //# sourceMappingURL=index-DoDNduO-.cjs.map