@safe-stars/components
Version:
React component library for buying Telegram Stars in Telegram Mini Apps via Safe Stars.
1 lines • 59.5 kB
Source Map (JSON)
{"version":3,"file":"index-DoDNduO-.cjs","sources":["../node_modules/@reown/appkit-controllers/dist/esm/src/utils/SwapApiUtil.js","../node_modules/@reown/appkit-controllers/dist/esm/src/utils/SwapCalculationUtil.js","../node_modules/@reown/appkit-controllers/dist/esm/src/controllers/SwapController.js","../node_modules/@reown/appkit-ui/dist/esm/src/composites/wui-token-button/styles.js","../node_modules/@reown/appkit-ui/dist/esm/src/composites/wui-token-button/index.js"],"sourcesContent":["import { AccountController } from '../controllers/AccountController.js';\nimport { BlockchainApiController } from '../controllers/BlockchainApiController.js';\nimport { ChainController } from '../controllers/ChainController.js';\nimport { ConnectionController } from '../controllers/ConnectionController.js';\n// -- Controller ---------------------------------------- //\nexport const SwapApiUtil = {\n async getTokenList() {\n const caipNetwork = ChainController.state.activeCaipNetwork;\n const response = await BlockchainApiController.fetchSwapTokens({\n chainId: caipNetwork?.caipNetworkId\n });\n const tokens = response?.tokens?.map(token => ({\n ...token,\n eip2612: false,\n quantity: {\n decimals: '0',\n numeric: '0'\n },\n price: 0,\n value: 0\n })) || [];\n return tokens;\n },\n async fetchGasPrice() {\n const caipNetwork = ChainController.state.activeCaipNetwork;\n if (!caipNetwork) {\n return null;\n }\n try {\n switch (caipNetwork.chainNamespace) {\n case 'solana':\n // eslint-disable-next-line no-case-declarations\n const lamportsPerSignature = (await ConnectionController?.estimateGas({ chainNamespace: 'solana' }))?.toString();\n return {\n standard: lamportsPerSignature,\n fast: lamportsPerSignature,\n instant: lamportsPerSignature\n };\n case 'eip155':\n default:\n return await BlockchainApiController.fetchGasPrice({\n chainId: caipNetwork.caipNetworkId\n });\n }\n }\n catch {\n return null;\n }\n },\n async fetchSwapAllowance({ tokenAddress, userAddress, sourceTokenAmount, sourceTokenDecimals }) {\n const response = await BlockchainApiController.fetchSwapAllowance({\n tokenAddress,\n userAddress\n });\n if (response?.allowance && sourceTokenAmount && sourceTokenDecimals) {\n const parsedValue = ConnectionController.parseUnits(sourceTokenAmount, sourceTokenDecimals) || 0;\n const hasAllowance = BigInt(response.allowance) >= parsedValue;\n return hasAllowance;\n }\n return false;\n },\n async getMyTokensWithBalance(forceUpdate) {\n const address = AccountController.state.address;\n const caipNetwork = ChainController.state.activeCaipNetwork;\n if (!address || !caipNetwork) {\n return [];\n }\n const response = await BlockchainApiController.getBalance(address, caipNetwork.caipNetworkId, forceUpdate);\n /*\n * The 1Inch API includes many low-quality tokens in the balance response,\n * which appear inconsistently. This filter prevents them from being displayed.\n */\n const balances = response.balances.filter(balance => balance.quantity.decimals !== '0');\n AccountController.setTokenBalance(balances, ChainController.state.activeChain);\n return this.mapBalancesToSwapTokens(balances);\n },\n mapBalancesToSwapTokens(balances) {\n return (balances?.map(token => ({\n ...token,\n address: token?.address\n ? token.address\n : ChainController.getActiveNetworkTokenAddress(),\n decimals: parseInt(token.quantity.decimals, 10),\n logoUri: token.iconUrl,\n eip2612: false\n })) || []);\n }\n};\n//# sourceMappingURL=SwapApiUtil.js.map","// -- Types --------------------------------------------- //\nimport { NumberUtil } from '@reown/appkit-common';\n// -- Util ---------------------------------------- //\nexport const SwapCalculationUtil = {\n getGasPriceInEther(gas, gasPrice) {\n const totalGasCostInWei = gasPrice * gas;\n const totalGasCostInEther = Number(totalGasCostInWei) / 1e18;\n return totalGasCostInEther;\n },\n getGasPriceInUSD(networkPrice, gas, gasPrice) {\n const totalGasCostInEther = SwapCalculationUtil.getGasPriceInEther(gas, gasPrice);\n const networkPriceInUSD = NumberUtil.bigNumber(networkPrice);\n const gasCostInUSD = networkPriceInUSD.times(totalGasCostInEther);\n return gasCostInUSD.toNumber();\n },\n getPriceImpact({ sourceTokenAmount, sourceTokenPriceInUSD, toTokenPriceInUSD, toTokenAmount }) {\n const inputValue = NumberUtil.bigNumber(sourceTokenAmount).times(sourceTokenPriceInUSD);\n const outputValue = NumberUtil.bigNumber(toTokenAmount).times(toTokenPriceInUSD);\n const priceImpact = inputValue.minus(outputValue).div(inputValue).times(100);\n return priceImpact.toNumber();\n },\n getMaxSlippage(slippage, toTokenAmount) {\n const slippageToleranceDecimal = NumberUtil.bigNumber(slippage).div(100);\n const maxSlippageAmount = NumberUtil.multiply(toTokenAmount, slippageToleranceDecimal);\n return maxSlippageAmount.toNumber();\n },\n getProviderFee(sourceTokenAmount, feePercentage = 0.0085) {\n const providerFee = NumberUtil.bigNumber(sourceTokenAmount).times(feePercentage);\n return providerFee.toString();\n },\n isInsufficientNetworkTokenForGas(networkBalanceInUSD, gasPriceInUSD) {\n const gasPrice = gasPriceInUSD || '0';\n if (NumberUtil.bigNumber(networkBalanceInUSD).eq(0)) {\n return true;\n }\n return NumberUtil.bigNumber(NumberUtil.bigNumber(gasPrice)).gt(networkBalanceInUSD);\n },\n isInsufficientSourceTokenForSwap(sourceTokenAmount, sourceTokenAddress, balance) {\n const sourceTokenBalance = balance?.find(token => token.address === sourceTokenAddress)\n ?.quantity?.numeric;\n const isInSufficientBalance = NumberUtil.bigNumber(sourceTokenBalance || '0').lt(sourceTokenAmount);\n return isInSufficientBalance;\n },\n getToTokenAmount({ sourceToken, toToken, sourceTokenPrice, toTokenPrice, sourceTokenAmount }) {\n if (sourceTokenAmount === '0') {\n return '0';\n }\n if (!sourceToken || !toToken) {\n return '0';\n }\n const sourceTokenDecimals = sourceToken.decimals;\n const sourceTokenPriceInUSD = sourceTokenPrice;\n const toTokenDecimals = toToken.decimals;\n const toTokenPriceInUSD = toTokenPrice;\n if (toTokenPriceInUSD <= 0) {\n return '0';\n }\n // Calculate the provider fee (0.85% of the source token amount)\n const providerFee = NumberUtil.bigNumber(sourceTokenAmount).times(0.0085);\n // Adjust the source token amount by subtracting the provider fee\n const adjustedSourceTokenAmount = NumberUtil.bigNumber(sourceTokenAmount).minus(providerFee);\n // Proceed with conversion using the adjusted source token amount\n const sourceAmountInSmallestUnit = adjustedSourceTokenAmount.times(NumberUtil.bigNumber(10).pow(sourceTokenDecimals));\n const priceRatio = NumberUtil.bigNumber(sourceTokenPriceInUSD).div(toTokenPriceInUSD);\n const decimalDifference = sourceTokenDecimals - toTokenDecimals;\n const toTokenAmountInSmallestUnit = sourceAmountInSmallestUnit\n .times(priceRatio)\n .div(NumberUtil.bigNumber(10).pow(decimalDifference));\n const toTokenAmount = toTokenAmountInSmallestUnit.div(NumberUtil.bigNumber(10).pow(toTokenDecimals));\n const amount = toTokenAmount.toFixed(toTokenDecimals).toString();\n return amount;\n }\n};\n//# sourceMappingURL=SwapCalculationUtil.js.map","import { proxy, subscribe as sub } from 'valtio/vanilla';\nimport { subscribeKey as subKey } from 'valtio/vanilla/utils';\nimport { NumberUtil } from '@reown/appkit-common';\nimport { ConstantsUtil as CommonConstantsUtil } from '@reown/appkit-common';\nimport { W3mFrameRpcConstants } from '@reown/appkit-wallet/utils';\nimport { ConstantsUtil } from '../utils/ConstantsUtil.js';\nimport { CoreHelperUtil } from '../utils/CoreHelperUtil.js';\nimport { SendApiUtil } from '../utils/SendApiUtil.js';\nimport { SwapApiUtil } from '../utils/SwapApiUtil.js';\nimport { SwapCalculationUtil } from '../utils/SwapCalculationUtil.js';\nimport { withErrorBoundary } from '../utils/withErrorBoundary.js';\nimport { AccountController } from './AccountController.js';\nimport { AlertController } from './AlertController.js';\nimport { BlockchainApiController } from './BlockchainApiController.js';\nimport { ChainController } from './ChainController.js';\nimport { ConnectionController } from './ConnectionController.js';\nimport { ConnectorController } from './ConnectorController.js';\nimport { EventsController } from './EventsController.js';\nimport { RouterController } from './RouterController.js';\nimport { SnackController } from './SnackController.js';\n// -- Constants ---------------------------------------- //\nexport const INITIAL_GAS_LIMIT = 150000;\nexport const TO_AMOUNT_DECIMALS = 6;\nclass TransactionError extends Error {\n constructor(message, shortMessage) {\n super(message);\n this.name = 'TransactionError';\n this.shortMessage = shortMessage;\n }\n}\n// -- State --------------------------------------------- //\nconst initialState = {\n // Loading states\n initializing: false,\n initialized: false,\n loadingPrices: false,\n loadingQuote: false,\n loadingApprovalTransaction: false,\n loadingBuildTransaction: false,\n loadingTransaction: false,\n // Error states\n fetchError: false,\n // Approval & Swap transaction states\n approvalTransaction: undefined,\n swapTransaction: undefined,\n transactionError: undefined,\n // Input values\n sourceToken: undefined,\n sourceTokenAmount: '',\n sourceTokenPriceInUSD: 0,\n toToken: undefined,\n toTokenAmount: '',\n toTokenPriceInUSD: 0,\n networkPrice: '0',\n networkBalanceInUSD: '0',\n networkTokenSymbol: '',\n inputError: undefined,\n // Request values\n slippage: ConstantsUtil.CONVERT_SLIPPAGE_TOLERANCE,\n // Tokens\n tokens: undefined,\n popularTokens: undefined,\n suggestedTokens: undefined,\n foundTokens: undefined,\n myTokensWithBalance: undefined,\n tokensPriceMap: {},\n // Calculations\n gasFee: '0',\n gasPriceInUSD: 0,\n priceImpact: undefined,\n maxSlippage: undefined,\n providerFee: undefined\n};\nconst state = proxy(initialState);\n// -- Controller ---------------------------------------- //\nconst controller = {\n state,\n subscribe(callback) {\n return sub(state, () => callback(state));\n },\n subscribeKey(key, callback) {\n return subKey(state, key, callback);\n },\n getParams() {\n const caipAddress = ChainController.state.activeCaipAddress;\n const namespace = ChainController.state.activeChain;\n const address = CoreHelperUtil.getPlainAddress(caipAddress);\n const networkAddress = ChainController.getActiveNetworkTokenAddress();\n const connectorId = ConnectorController.getConnectorId(namespace);\n if (!address) {\n throw new Error('No address found to swap the tokens from.');\n }\n const invalidToToken = !state.toToken?.address || !state.toToken?.decimals;\n const invalidSourceToken = !state.sourceToken?.address ||\n !state.sourceToken?.decimals ||\n !NumberUtil.bigNumber(state.sourceTokenAmount).gt(0);\n const invalidSourceTokenAmount = !state.sourceTokenAmount;\n return {\n networkAddress,\n fromAddress: address,\n fromCaipAddress: caipAddress,\n sourceTokenAddress: state.sourceToken?.address,\n toTokenAddress: state.toToken?.address,\n toTokenAmount: state.toTokenAmount,\n toTokenDecimals: state.toToken?.decimals,\n sourceTokenAmount: state.sourceTokenAmount,\n sourceTokenDecimals: state.sourceToken?.decimals,\n invalidToToken,\n invalidSourceToken,\n invalidSourceTokenAmount,\n availableToSwap: caipAddress && !invalidToToken && !invalidSourceToken && !invalidSourceTokenAmount,\n isAuthConnector: connectorId === CommonConstantsUtil.CONNECTOR_ID.AUTH\n };\n },\n setSourceToken(sourceToken) {\n if (!sourceToken) {\n state.sourceToken = sourceToken;\n state.sourceTokenAmount = '';\n state.sourceTokenPriceInUSD = 0;\n return;\n }\n state.sourceToken = sourceToken;\n SwapController.setTokenPrice(sourceToken.address, 'sourceToken');\n },\n setSourceTokenAmount(amount) {\n state.sourceTokenAmount = amount;\n },\n setToToken(toToken) {\n if (!toToken) {\n state.toToken = toToken;\n state.toTokenAmount = '';\n state.toTokenPriceInUSD = 0;\n return;\n }\n state.toToken = toToken;\n SwapController.setTokenPrice(toToken.address, 'toToken');\n },\n setToTokenAmount(amount) {\n state.toTokenAmount = amount\n ? NumberUtil.formatNumberToLocalString(amount, TO_AMOUNT_DECIMALS)\n : '';\n },\n async setTokenPrice(address, target) {\n let price = state.tokensPriceMap[address] || 0;\n if (!price) {\n state.loadingPrices = true;\n price = await SwapController.getAddressPrice(address);\n }\n if (target === 'sourceToken') {\n state.sourceTokenPriceInUSD = price;\n }\n else if (target === 'toToken') {\n state.toTokenPriceInUSD = price;\n }\n if (state.loadingPrices) {\n state.loadingPrices = false;\n }\n if (SwapController.getParams().availableToSwap) {\n SwapController.swapTokens();\n }\n },\n switchTokens() {\n if (state.initializing || !state.initialized) {\n return;\n }\n const newSourceToken = state.toToken ? { ...state.toToken } : undefined;\n const newToToken = state.sourceToken ? { ...state.sourceToken } : undefined;\n const newSourceTokenAmount = newSourceToken && state.toTokenAmount === '' ? '1' : state.toTokenAmount;\n SwapController.setSourceToken(newSourceToken);\n SwapController.setToToken(newToToken);\n SwapController.setSourceTokenAmount(newSourceTokenAmount);\n SwapController.setToTokenAmount('');\n SwapController.swapTokens();\n },\n resetState() {\n state.myTokensWithBalance = initialState.myTokensWithBalance;\n state.tokensPriceMap = initialState.tokensPriceMap;\n state.initialized = initialState.initialized;\n state.sourceToken = initialState.sourceToken;\n state.sourceTokenAmount = initialState.sourceTokenAmount;\n state.sourceTokenPriceInUSD = initialState.sourceTokenPriceInUSD;\n state.toToken = initialState.toToken;\n state.toTokenAmount = initialState.toTokenAmount;\n state.toTokenPriceInUSD = initialState.toTokenPriceInUSD;\n state.networkPrice = initialState.networkPrice;\n state.networkTokenSymbol = initialState.networkTokenSymbol;\n state.networkBalanceInUSD = initialState.networkBalanceInUSD;\n state.inputError = initialState.inputError;\n state.myTokensWithBalance = initialState.myTokensWithBalance;\n },\n resetValues() {\n const { networkAddress } = SwapController.getParams();\n const networkToken = state.tokens?.find(token => token.address === networkAddress);\n SwapController.setSourceToken(networkToken);\n SwapController.setToToken(undefined);\n },\n getApprovalLoadingState() {\n return state.loadingApprovalTransaction;\n },\n clearError() {\n state.transactionError = undefined;\n },\n async initializeState() {\n if (state.initializing) {\n return;\n }\n state.initializing = true;\n if (!state.initialized) {\n try {\n await SwapController.fetchTokens();\n state.initialized = true;\n }\n catch (error) {\n state.initialized = false;\n SnackController.showError('Failed to initialize swap');\n RouterController.goBack();\n }\n }\n state.initializing = false;\n },\n async fetchTokens() {\n const { networkAddress } = SwapController.getParams();\n await SwapController.getTokenList();\n await SwapController.getNetworkTokenPrice();\n await SwapController.getMyTokensWithBalance();\n const networkToken = state.tokens?.find(token => token.address === networkAddress);\n if (networkToken) {\n state.networkTokenSymbol = networkToken.symbol;\n SwapController.setSourceToken(networkToken);\n SwapController.setSourceTokenAmount('1');\n }\n },\n async getTokenList() {\n const tokens = await SwapApiUtil.getTokenList();\n state.tokens = tokens;\n state.popularTokens = tokens.sort((aTokenInfo, bTokenInfo) => {\n if (aTokenInfo.symbol < bTokenInfo.symbol) {\n return -1;\n }\n if (aTokenInfo.symbol > bTokenInfo.symbol) {\n return 1;\n }\n return 0;\n });\n state.suggestedTokens = tokens.filter(token => {\n if (ConstantsUtil.SWAP_SUGGESTED_TOKENS.includes(token.symbol)) {\n return true;\n }\n return false;\n }, {});\n },\n async getAddressPrice(address) {\n const existPrice = state.tokensPriceMap[address];\n if (existPrice) {\n return existPrice;\n }\n const response = await BlockchainApiController.fetchTokenPrice({\n addresses: [address]\n });\n const fungibles = response?.fungibles || [];\n const allTokens = [...(state.tokens || []), ...(state.myTokensWithBalance || [])];\n const symbol = allTokens?.find(token => token.address === address)?.symbol;\n const price = fungibles.find(p => p.symbol.toLowerCase() === symbol?.toLowerCase())?.price || 0;\n const priceAsFloat = parseFloat(price.toString());\n state.tokensPriceMap[address] = priceAsFloat;\n return priceAsFloat;\n },\n async getNetworkTokenPrice() {\n const { networkAddress } = SwapController.getParams();\n const response = await BlockchainApiController.fetchTokenPrice({\n addresses: [networkAddress]\n }).catch(() => {\n SnackController.showError('Failed to fetch network token price');\n return { fungibles: [] };\n });\n const token = response.fungibles?.[0];\n const price = token?.price.toString() || '0';\n state.tokensPriceMap[networkAddress] = parseFloat(price);\n state.networkTokenSymbol = token?.symbol || '';\n state.networkPrice = price;\n },\n async getMyTokensWithBalance(forceUpdate) {\n const balances = await SendApiUtil.getMyTokensWithBalance(forceUpdate);\n const swapBalances = SendApiUtil.mapBalancesToSwapTokens(balances);\n if (!swapBalances) {\n return;\n }\n await SwapController.getInitialGasPrice();\n SwapController.setBalances(swapBalances);\n },\n setBalances(balances) {\n const { networkAddress } = SwapController.getParams();\n const caipNetwork = ChainController.state.activeCaipNetwork;\n if (!caipNetwork) {\n return;\n }\n const networkToken = balances.find(token => token.address === networkAddress);\n balances.forEach(token => {\n state.tokensPriceMap[token.address] = token.price || 0;\n });\n state.myTokensWithBalance = balances.filter(token => token.address.startsWith(caipNetwork.caipNetworkId));\n state.networkBalanceInUSD = networkToken\n ? NumberUtil.multiply(networkToken.quantity.numeric, networkToken.price).toString()\n : '0';\n },\n async getInitialGasPrice() {\n const res = await SwapApiUtil.fetchGasPrice();\n if (!res) {\n return { gasPrice: null, gasPriceInUSD: null };\n }\n switch (ChainController.state?.activeCaipNetwork?.chainNamespace) {\n case 'solana':\n state.gasFee = res.standard ?? '0';\n state.gasPriceInUSD = NumberUtil.multiply(res.standard, state.networkPrice)\n .div(1e9)\n .toNumber();\n return {\n gasPrice: BigInt(state.gasFee),\n gasPriceInUSD: Number(state.gasPriceInUSD)\n };\n case 'eip155':\n default:\n // eslint-disable-next-line no-case-declarations\n const value = res.standard ?? '0';\n // eslint-disable-next-line no-case-declarations\n const gasFee = BigInt(value);\n // eslint-disable-next-line no-case-declarations\n const gasLimit = BigInt(INITIAL_GAS_LIMIT);\n // eslint-disable-next-line no-case-declarations\n const gasPrice = SwapCalculationUtil.getGasPriceInUSD(state.networkPrice, gasLimit, gasFee);\n state.gasFee = value;\n state.gasPriceInUSD = gasPrice;\n return { gasPrice: gasFee, gasPriceInUSD: gasPrice };\n }\n },\n // -- Swap -------------------------------------- //\n async swapTokens() {\n const address = AccountController.state.address;\n const sourceToken = state.sourceToken;\n const toToken = state.toToken;\n const haveSourceTokenAmount = NumberUtil.bigNumber(state.sourceTokenAmount).gt(0);\n if (!haveSourceTokenAmount) {\n SwapController.setToTokenAmount('');\n }\n if (!toToken || !sourceToken || state.loadingPrices || !haveSourceTokenAmount) {\n return;\n }\n state.loadingQuote = true;\n const amountDecimal = NumberUtil.bigNumber(state.sourceTokenAmount)\n .times(10 ** sourceToken.decimals)\n .round(0);\n try {\n const quoteResponse = await BlockchainApiController.fetchSwapQuote({\n userAddress: address,\n from: sourceToken.address,\n to: toToken.address,\n gasPrice: state.gasFee,\n amount: amountDecimal.toString()\n });\n state.loadingQuote = false;\n const quoteToAmount = quoteResponse?.quotes?.[0]?.toAmount;\n if (!quoteToAmount) {\n AlertController.open({\n shortMessage: 'Incorrect amount',\n longMessage: 'Please enter a valid amount'\n }, 'error');\n return;\n }\n const toTokenAmount = NumberUtil.bigNumber(quoteToAmount)\n .div(10 ** toToken.decimals)\n .toString();\n SwapController.setToTokenAmount(toTokenAmount);\n const isInsufficientToken = SwapController.hasInsufficientToken(state.sourceTokenAmount, sourceToken.address);\n if (isInsufficientToken) {\n state.inputError = 'Insufficient balance';\n }\n else {\n state.inputError = undefined;\n SwapController.setTransactionDetails();\n }\n }\n catch (error) {\n state.loadingQuote = false;\n state.inputError = 'Insufficient balance';\n }\n },\n // -- Create Transactions -------------------------------------- //\n async getTransaction() {\n const { fromCaipAddress, availableToSwap } = SwapController.getParams();\n const sourceToken = state.sourceToken;\n const toToken = state.toToken;\n if (!fromCaipAddress || !availableToSwap || !sourceToken || !toToken || state.loadingQuote) {\n return undefined;\n }\n try {\n state.loadingBuildTransaction = true;\n const hasAllowance = await SwapApiUtil.fetchSwapAllowance({\n userAddress: fromCaipAddress,\n tokenAddress: sourceToken.address,\n sourceTokenAmount: state.sourceTokenAmount,\n sourceTokenDecimals: sourceToken.decimals\n });\n let transaction = undefined;\n if (hasAllowance) {\n transaction = await SwapController.createSwapTransaction();\n }\n else {\n transaction = await SwapController.createAllowanceTransaction();\n }\n state.loadingBuildTransaction = false;\n state.fetchError = false;\n return transaction;\n }\n catch (error) {\n RouterController.goBack();\n SnackController.showError('Failed to check allowance');\n state.loadingBuildTransaction = false;\n state.approvalTransaction = undefined;\n state.swapTransaction = undefined;\n state.fetchError = true;\n return undefined;\n }\n },\n async createAllowanceTransaction() {\n const { fromCaipAddress, sourceTokenAddress, toTokenAddress } = SwapController.getParams();\n if (!fromCaipAddress || !toTokenAddress) {\n return undefined;\n }\n if (!sourceTokenAddress) {\n throw new Error('createAllowanceTransaction - No source token address found.');\n }\n try {\n const response = await BlockchainApiController.generateApproveCalldata({\n from: sourceTokenAddress,\n to: toTokenAddress,\n userAddress: fromCaipAddress\n });\n const transaction = {\n data: response.tx.data,\n to: CoreHelperUtil.getPlainAddress(response.tx.from),\n gasPrice: BigInt(response.tx.eip155.gasPrice),\n value: BigInt(response.tx.value),\n toAmount: state.toTokenAmount\n };\n state.swapTransaction = undefined;\n state.approvalTransaction = {\n data: transaction.data,\n to: transaction.to,\n gasPrice: transaction.gasPrice,\n value: transaction.value,\n toAmount: transaction.toAmount\n };\n return {\n data: transaction.data,\n to: transaction.to,\n gasPrice: transaction.gasPrice,\n value: transaction.value,\n toAmount: transaction.toAmount\n };\n }\n catch (error) {\n RouterController.goBack();\n SnackController.showError('Failed to create approval transaction');\n state.approvalTransaction = undefined;\n state.swapTransaction = undefined;\n state.fetchError = true;\n return undefined;\n }\n },\n async createSwapTransaction() {\n const { networkAddress, fromCaipAddress, sourceTokenAmount } = SwapController.getParams();\n const sourceToken = state.sourceToken;\n const toToken = state.toToken;\n if (!fromCaipAddress || !sourceTokenAmount || !sourceToken || !toToken) {\n return undefined;\n }\n const amount = ConnectionController.parseUnits(sourceTokenAmount, sourceToken.decimals)?.toString();\n try {\n const response = await BlockchainApiController.generateSwapCalldata({\n userAddress: fromCaipAddress,\n from: sourceToken.address,\n to: toToken.address,\n amount: amount,\n disableEstimate: true\n });\n const isSourceTokenIsNetworkToken = sourceToken.address === networkAddress;\n const gas = BigInt(response.tx.eip155.gas);\n const gasPrice = BigInt(response.tx.eip155.gasPrice);\n const transaction = {\n data: response.tx.data,\n to: CoreHelperUtil.getPlainAddress(response.tx.to),\n gas,\n gasPrice,\n value: isSourceTokenIsNetworkToken ? BigInt(amount ?? '0') : BigInt('0'),\n toAmount: state.toTokenAmount\n };\n state.gasPriceInUSD = SwapCalculationUtil.getGasPriceInUSD(state.networkPrice, gas, gasPrice);\n state.approvalTransaction = undefined;\n state.swapTransaction = transaction;\n return transaction;\n }\n catch (error) {\n RouterController.goBack();\n SnackController.showError('Failed to create transaction');\n state.approvalTransaction = undefined;\n state.swapTransaction = undefined;\n state.fetchError = true;\n return undefined;\n }\n },\n // -- Send Transactions --------------------------------- //\n async sendTransactionForApproval(data) {\n const { fromAddress, isAuthConnector } = SwapController.getParams();\n state.loadingApprovalTransaction = true;\n const approveLimitMessage = `Approve limit increase in your wallet`;\n if (isAuthConnector) {\n RouterController.pushTransactionStack({\n view: null,\n goBack: true,\n onSuccess() {\n SnackController.showLoading(approveLimitMessage);\n }\n });\n }\n else {\n SnackController.showLoading(approveLimitMessage);\n }\n try {\n await ConnectionController.sendTransaction({\n address: fromAddress,\n to: data.to,\n data: data.data,\n value: data.value,\n chainNamespace: 'eip155'\n });\n await SwapController.swapTokens();\n await SwapController.getTransaction();\n state.approvalTransaction = undefined;\n state.loadingApprovalTransaction = false;\n }\n catch (err) {\n const error = err;\n state.transactionError = error?.shortMessage;\n state.loadingApprovalTransaction = false;\n SnackController.showError(error?.shortMessage || 'Transaction error');\n EventsController.sendEvent({\n type: 'track',\n event: 'SWAP_APPROVAL_ERROR',\n properties: {\n message: error?.shortMessage || error?.message || 'Unknown',\n network: ChainController.state.activeCaipNetwork?.caipNetworkId || '',\n swapFromToken: SwapController.state.sourceToken?.symbol || '',\n swapToToken: SwapController.state.toToken?.symbol || '',\n swapFromAmount: SwapController.state.sourceTokenAmount || '',\n swapToAmount: SwapController.state.toTokenAmount || '',\n isSmartAccount: AccountController.state.preferredAccountTypes?.eip155 ===\n W3mFrameRpcConstants.ACCOUNT_TYPES.SMART_ACCOUNT\n }\n });\n }\n },\n async sendTransactionForSwap(data) {\n if (!data) {\n return undefined;\n }\n const { fromAddress, toTokenAmount, isAuthConnector } = SwapController.getParams();\n state.loadingTransaction = true;\n const snackbarPendingMessage = `Swapping ${state.sourceToken?.symbol} to ${NumberUtil.formatNumberToLocalString(toTokenAmount, 3)} ${state.toToken?.symbol}`;\n const snackbarSuccessMessage = `Swapped ${state.sourceToken?.symbol} to ${NumberUtil.formatNumberToLocalString(toTokenAmount, 3)} ${state.toToken?.symbol}`;\n if (isAuthConnector) {\n RouterController.pushTransactionStack({\n view: 'Account',\n goBack: false,\n onSuccess() {\n SnackController.showLoading(snackbarPendingMessage);\n controller.resetState();\n }\n });\n }\n else {\n SnackController.showLoading('Confirm transaction in your wallet');\n }\n try {\n const forceUpdateAddresses = [state.sourceToken?.address, state.toToken?.address].join(',');\n const transactionHash = await ConnectionController.sendTransaction({\n address: fromAddress,\n to: data.to,\n data: data.data,\n value: data.value,\n chainNamespace: 'eip155'\n });\n state.loadingTransaction = false;\n SnackController.showSuccess(snackbarSuccessMessage);\n EventsController.sendEvent({\n type: 'track',\n event: 'SWAP_SUCCESS',\n properties: {\n network: ChainController.state.activeCaipNetwork?.caipNetworkId || '',\n swapFromToken: SwapController.state.sourceToken?.symbol || '',\n swapToToken: SwapController.state.toToken?.symbol || '',\n swapFromAmount: SwapController.state.sourceTokenAmount || '',\n swapToAmount: SwapController.state.toTokenAmount || '',\n isSmartAccount: AccountController.state.preferredAccountTypes?.eip155 ===\n W3mFrameRpcConstants.ACCOUNT_TYPES.SMART_ACCOUNT\n }\n });\n controller.resetState();\n if (!isAuthConnector) {\n RouterController.replace('Account');\n }\n controller.getMyTokensWithBalance(forceUpdateAddresses);\n return transactionHash;\n }\n catch (err) {\n const error = err;\n state.transactionError = error?.shortMessage;\n state.loadingTransaction = false;\n SnackController.showError(error?.shortMessage || 'Transaction error');\n EventsController.sendEvent({\n type: 'track',\n event: 'SWAP_ERROR',\n properties: {\n message: error?.shortMessage || error?.message || 'Unknown',\n network: ChainController.state.activeCaipNetwork?.caipNetworkId || '',\n swapFromToken: SwapController.state.sourceToken?.symbol || '',\n swapToToken: SwapController.state.toToken?.symbol || '',\n swapFromAmount: SwapController.state.sourceTokenAmount || '',\n swapToAmount: SwapController.state.toTokenAmount || '',\n isSmartAccount: AccountController.state.preferredAccountTypes?.eip155 ===\n W3mFrameRpcConstants.ACCOUNT_TYPES.SMART_ACCOUNT\n }\n });\n return undefined;\n }\n },\n // -- Checks -------------------------------------------- //\n hasInsufficientToken(sourceTokenAmount, sourceTokenAddress) {\n const isInsufficientSourceTokenForSwap = SwapCalculationUtil.isInsufficientSourceTokenForSwap(sourceTokenAmount, sourceTokenAddress, state.myTokensWithBalance);\n return isInsufficientSourceTokenForSwap;\n },\n // -- Calculations -------------------------------------- //\n setTransactionDetails() {\n const { toTokenAddress, toTokenDecimals } = SwapController.getParams();\n if (!toTokenAddress || !toTokenDecimals) {\n return;\n }\n state.gasPriceInUSD = SwapCalculationUtil.getGasPriceInUSD(state.networkPrice, BigInt(state.gasFee), BigInt(INITIAL_GAS_LIMIT));\n state.priceImpact = SwapCalculationUtil.getPriceImpact({\n sourceTokenAmount: state.sourceTokenAmount,\n sourceTokenPriceInUSD: state.sourceTokenPriceInUSD,\n toTokenPriceInUSD: state.toTokenPriceInUSD,\n toTokenAmount: state.toTokenAmount\n });\n state.maxSlippage = SwapCalculationUtil.getMaxSlippage(state.slippage, state.toTokenAmount);\n state.providerFee = SwapCalculationUtil.getProviderFee(state.sourceTokenAmount);\n }\n};\n// Export the controller wrapped with our error boundary\nexport const SwapController = withErrorBoundary(controller);\n//# sourceMappingURL=SwapController.js.map","import { css } from 'lit';\nexport default css `\n :host {\n display: block;\n }\n\n :host > button {\n gap: var(--wui-spacing-xxs);\n padding: var(--wui-spacing-xs);\n padding-right: var(--wui-spacing-1xs);\n height: 40px;\n border-radius: var(--wui-border-radius-l);\n background: var(--wui-color-gray-glass-002);\n border-width: 0px;\n box-shadow: inset 0 0 0 1px var(--wui-color-gray-glass-002);\n }\n\n :host > button wui-image {\n width: 24px;\n height: 24px;\n border-radius: var(--wui-border-radius-s);\n box-shadow: inset 0 0 0 1px var(--wui-color-gray-glass-010);\n }\n`;\n//# sourceMappingURL=styles.js.map","var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n};\nimport { LitElement, html } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport '../../components/wui-image/index.js';\nimport '../../components/wui-text/index.js';\nimport { elementStyles, resetStyles } from '../../utils/ThemeUtil.js';\nimport { customElement } from '../../utils/WebComponentsUtil.js';\nimport '../wui-icon-box/index.js';\nimport styles from './styles.js';\nlet WuiTokenButton = class WuiTokenButton extends LitElement {\n constructor() {\n super(...arguments);\n this.text = '';\n }\n render() {\n return html `\n <button>\n ${this.tokenTemplate()}\n <wui-text variant=\"paragraph-600\" color=\"fg-100\">${this.text}</wui-text>\n </button>\n `;\n }\n tokenTemplate() {\n if (this.imageSrc) {\n return html `<wui-image src=${this.imageSrc}></wui-image>`;\n }\n return html `\n <wui-icon-box\n size=\"sm\"\n iconColor=\"fg-200\"\n backgroundColor=\"fg-300\"\n icon=\"networkPlaceholder\"\n ></wui-icon-box>\n `;\n }\n};\nWuiTokenButton.styles = [resetStyles, elementStyles, styles];\n__decorate([\n property()\n], WuiTokenButton.prototype, \"imageSrc\", void 0);\n__decorate([\n property()\n], WuiTokenButton.prototype, \"text\", void 0);\nWuiTokenButton = __decorate([\n customElement('wui-token-button')\n], WuiTokenButton);\nexport { WuiTokenButton };\n//# sourceMappingURL=index.js.map"],"names":["SwapApiUtil","caipNetwork","ChainController","response","BlockchainApiController","_a","token","lamportsPerSignature","_b","ConnectionController","tokenAddress","userAddress","sourceTokenAmount","sourceTokenDecimals","parsedValue","forceUpdate","address","AccountController","balances","balance","SwapCalculationUtil","gas","gasPrice","totalGasCostInWei","networkPrice","totalGasCostInEther","NumberUtil","sourceTokenPriceInUSD","toTokenPriceInUSD","toTokenAmount","inputValue","outputValue","slippage","slippageToleranceDecimal","feePercentage","networkBalanceInUSD","gasPriceInUSD","sourceTokenAddress","sourceTokenBalance","sourceToken","toToken","sourceTokenPrice","toTokenPrice","toTokenDecimals","providerFee","sourceAmountInSmallestUnit","priceRatio","decimalDifference","INITIAL_GAS_LIMIT","TO_AMOUNT_DECIMALS","initialState","ConstantsUtil","state","proxy","controller","callback","sub","key","subKey","caipAddress","namespace","CoreHelperUtil","networkAddress","connectorId","ConnectorController","invalidToToken","invalidSourceToken","_c","_d","invalidSourceTokenAmount","_e","_f","_g","_h","CommonConstantsUtil","SwapController","amount","target","price","newSourceToken","newToToken","newSourceTokenAmount","networkToken","SnackController","RouterController","tokens","aTokenInfo","bTokenInfo","existPrice","fungibles","allTokens","symbol","p","priceAsFloat","SendApiUtil","swapBalances","res","value","gasFee","gasLimit","haveSourceTokenAmount","amountDecimal","quoteResponse","quoteToAmount","AlertController","fromCaipAddress","availableToSwap","hasAllowance","transaction","toTokenAddress","isSourceTokenIsNetworkToken","data","fromAddress","isAuthConnector","approveLimitMessage","err","error","EventsController","W3mFrameRpcConstants","snackbarPendingMessage","snackbarSuccessMessage","forceUpdateAddresses","transactionHash","_i","_l","_m","withErrorBoundary","css","__decorate","decorators","desc","c","r","d","i","WuiTokenButton","LitElement","html","resetStyles","elementStyles","styles","property","customElement"],"mappings":"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