@ape.swap/bonds-sdk 6.1.15-test.0 → 6.1.17-test.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.
Files changed (52) hide show
  1. package/dist/components/ConnectButton/index.js +3 -4
  2. package/dist/components/ConnectButton/index.js.map +1 -1
  3. package/dist/components/ConnectSolanaWalletButton/ConnectSolanaWalletButton.js +5 -3
  4. package/dist/components/ConnectSolanaWalletButton/ConnectSolanaWalletButton.js.map +1 -1
  5. package/dist/components/ConnectoToVmBanners/ConnectToAptosBanner.js +7 -2
  6. package/dist/components/ConnectoToVmBanners/ConnectToAptosBanner.js.map +1 -1
  7. package/dist/components/ConnectoToVmBanners/ConnectToSolanaBanner.js +5 -1
  8. package/dist/components/ConnectoToVmBanners/ConnectToSolanaBanner.js.map +1 -1
  9. package/dist/components/ConnectoToVmBanners/ConnectToSuiBanner.js +9 -2
  10. package/dist/components/ConnectoToVmBanners/ConnectToSuiBanner.js.map +1 -1
  11. package/dist/config/constants/aptosZapTokens.js +1 -15
  12. package/dist/config/constants/aptosZapTokens.js.map +1 -1
  13. package/dist/config/constants/walletConnectors.d.ts +6 -0
  14. package/dist/config/constants/walletConnectors.js +25 -0
  15. package/dist/config/constants/walletConnectors.js.map +1 -0
  16. package/dist/constants/aptosConstants.js +1 -5
  17. package/dist/constants/aptosConstants.js.map +1 -1
  18. package/dist/constants/suiConstants.js +1 -3
  19. package/dist/constants/suiConstants.js.map +1 -1
  20. package/dist/state/useSDKConfig.d.ts +13 -3
  21. package/dist/state/useSDKConfig.js +22 -10
  22. package/dist/state/useSDKConfig.js.map +1 -1
  23. package/dist/utils/aptosHelpers.js +1 -25
  24. package/dist/utils/aptosHelpers.js.map +1 -1
  25. package/dist/views/BuyBond/BuyBondModal.js +14 -3
  26. package/dist/views/BuyBond/BuyBondModal.js.map +1 -1
  27. package/dist/views/YourBonds/components/UserBondRow/UserBondRowSolana.js +3 -1
  28. package/dist/views/YourBonds/components/UserBondRow/UserBondRowSolana.js.map +1 -1
  29. package/dist/views/YourBondsModal/components/TransferBondModal/TransferActionSolana.js +5 -1
  30. package/dist/views/YourBondsModal/components/TransferBondModal/TransferActionSolana.js.map +1 -1
  31. package/package.json +1 -2
  32. package/dist/components/ConnectAptosWalletButton/ConnectAptosWalletButton.js +0 -39
  33. package/dist/components/ConnectAptosWalletButton/ConnectAptosWalletButton.js.map +0 -1
  34. package/dist/components/ConnectButton/AppKitButton.d.ts +0 -3
  35. package/dist/components/ConnectButton/AppKitButton.js +0 -9
  36. package/dist/components/ConnectButton/AppKitButton.js.map +0 -1
  37. package/dist/components/ConnectButton/RainbowKitButton.d.ts +0 -3
  38. package/dist/components/ConnectButton/RainbowKitButton.js +0 -22
  39. package/dist/components/ConnectButton/RainbowKitButton.js.map +0 -1
  40. package/dist/config/constants/suiCallbacks.d.ts +0 -2
  41. package/dist/config/constants/suiCallbacks.js +0 -17
  42. package/dist/config/constants/suiCallbacks.js.map +0 -1
  43. package/dist/config/constants/suiZapTokens.js +0 -36
  44. package/dist/config/constants/suiZapTokens.js.map +0 -1
  45. package/dist/state/zap/useAptosZapQuote.js +0 -83
  46. package/dist/state/zap/useAptosZapQuote.js.map +0 -1
  47. package/dist/state/zap/useSuiZapQuote.js +0 -96
  48. package/dist/state/zap/useSuiZapQuote.js.map +0 -1
  49. package/dist/views/BuyBond/BuyComponentAptos.js +0 -349
  50. package/dist/views/BuyBond/BuyComponentAptos.js.map +0 -1
  51. package/dist/views/BuyBond/BuyComponentSui.js +0 -500
  52. package/dist/views/BuyBond/BuyComponentSui.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"BuyComponentAptos.js","sources":["../../../src/views/BuyBond/BuyComponentAptos.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useState } from 'react'\nimport BigNumber from 'bignumber.js'\nimport { ChainId, MarketingCampaign } from '@ape.swap/apeswap-lists'\n\nimport useBondsData from '../../state/bonds/useBondsData'\nimport { useSDKConfig } from '../../state/useSDKConfig'\nimport { usePopups } from '../../state/popups/usePopups'\nimport { useSlippage } from '../../state/slippage/useSlippage'\nimport { BondsData } from '../../types/bonds'\nimport { formatUSDNumber, getMaxBuy, getPayoutAmount, getPrincipalAmount } from '../../utils/displayHelpers'\nimport { formatNumberSI } from '../../utils/formatNumber'\nimport { findHighestTrueBondPrice } from '../../utils/bondPriceHelpers'\nimport { reportError } from '../../utils/reportError'\nimport { MCBuyComponentStyles } from '../../utils/campaignStyles'\nimport track from '../../utils/track'\nimport { remove0xPrefix } from '../../utils/remove0xPrefix'\nimport { getSymbol } from '../../utils/getNativeTicker'\n\nimport useAPTAccount from '../../hooks/accounts/useAPTAccount'\nimport useTokenFromZapList from '../../hooks/useTokenFromZapList'\nimport useSortedZapList from '../../hooks/useSortedZapList'\nimport useAptosZapQuote from '../../state/zap/useAptosZapQuote'\nimport { findAptosZapToken } from '../../config/constants/aptosZapTokens'\nimport ConnectAptosWalletButton from '../../components/ConnectAptosWalletButton/ConnectAptosWalletButton'\nimport TokenSelectorPanel from '../../components/TokenSelectorPanel'\nimport BondModalHeader from './components/BondModalHeader'\nimport BondCards from './components/BondCards/BondCards'\nimport Estimations from './components/Estimations'\nimport ProjectDescription from './components/ProjectDescription'\n\nimport Flex from '../../components/uikit-sdk/Flex'\nimport Text from '../../components/uikit-sdk/Text'\nimport Button from '../../components/uikit-sdk/Button/Button'\nimport SafeHTMLComponent from '../../components/SafeHTMLComponent'\n\nimport { APTOS_DEPOSIT_FUNCTION } from '../../constants/aptosConstants'\nimport { extractBillMinted, extractDepositEvent, getAptosClient, readAptosMarketInfo } from '../../utils/aptosHelpers'\n\nexport interface BuyComponentAptosProps {\n onDismiss?: () => void\n bondAddress?: string\n bondChain?: number\n setBillId?: (id: string) => void\n isProjectView?: boolean\n}\n\nconst BuyComponentAptos: React.FC<BuyComponentAptosProps> = ({\n onDismiss,\n bondAddress,\n bondChain,\n isProjectView,\n setBillId,\n}) => {\n const SDKConfig = useSDKConfig()\n\n // Hooks\n const { address: aptosAccount, signAndSubmitTransaction } = useAPTAccount()\n const { data: bonds } = useBondsData()\n const { addToastError, addToastSuccess } = usePopups()\n const { solSlippage: slippage } = useSlippage() // reuse Sol slippage bucket for Aptos\n\n const bondData: BondsData | undefined = bonds?.find(\n (bond) => bond?.contractAddress?.[bond?.chainId]?.toLowerCase() === bondAddress?.toLowerCase(),\n )\n\n // Derived pricing (same path the Solana no-tier branch uses).\n const trueBondPriceData = findHighestTrueBondPrice('0', bondData?.trueBondPrices)\n\n // State\n const [inputValue, setInputValue] = useState('')\n const [inputTokenString, setInputTokenString] = useState(bondData?.lpToken?.address?.[bondData?.chainId])\n const [loadingTx, setLoadingTx] = useState(false)\n\n // Token selection — reuses the same infrastructure as Solana\n const inputToken = useTokenFromZapList(inputTokenString, bondData?.chainId, bondData?.lpToken)\n const principalAddress = bondData?.lpToken?.address?.[bondData?.chainId]\n // APT native ('NATIVE') and APT metadata ('0xa') are the same token — not a zap\n const isNativeMatchingPrincipal = inputTokenString === 'NATIVE' && principalAddress?.toLowerCase() === '0xa'\n const isZap =\n !!inputTokenString &&\n !!principalAddress &&\n !isNativeMatchingPrincipal &&\n inputTokenString.toLowerCase() !== principalAddress.toLowerCase()\n\n // Zap quote from Panora DEX aggregator\n const aptosZapToken = findAptosZapToken(\n inputToken && inputToken !== 'NATIVE'\n ? inputToken?.address?.[ChainId.APTOS]\n : inputToken === 'NATIVE'\n ? '0xa'\n : undefined,\n )\n const [fetchingZapQuote, panoraQuote, zapDepositAmount, zapError] = useAptosZapQuote(\n inputValue,\n aptosZapToken,\n bondData,\n aptosAccount,\n slippage,\n )\n\n // Sorted zap list (balances + prices)\n const { sortedZapList, isFetched: zapListFetched } = useSortedZapList(bondChain, bondData?.lpToken)\n const enrichedTokenData = sortedZapList.find((item) =>\n item.token === 'NATIVE' || inputToken === 'NATIVE'\n ? item.token === inputToken\n : item?.token?.address?.[bondChain as ChainId]?.toLowerCase() ===\n inputToken?.address?.[bondChain as ChainId]?.toLowerCase(),\n )\n const inputCurrencyBalance = enrichedTokenData?.balance\n const inputTokenPrice = enrichedTokenData?.price\n\n // Estimations — use zapDepositAmount if swapping\n const depositAmount = isZap ? zapDepositAmount : inputValue\n const youSpendString = `${formatNumberSI(inputValue)} ${getSymbol(inputToken, bondData?.chainId)} = $${formatUSDNumber(\n (parseFloat(inputValue || '0') * (inputTokenPrice ?? 0)).toString(),\n )}`\n\n const exceedsRealMaxBuy = getMaxBuy(bondData, true).lte(getPayoutAmount(bondData, depositAmount, '0'))\n const exceedsSafeMaxBuy = getMaxBuy(bondData, false)\n .times(isZap ? 0.995 : 0.9995)\n .lte(getPayoutAmount(bondData, depositAmount, '0'))\n const exceedsBalance = new BigNumber(inputCurrencyBalance ?? '0').lt(inputValue)\n\n const load = loadingTx || (fetchingZapQuote && !!inputValue)\n\n // Handlers\n const handleCurrencySelect = useCallback((newInputToken: string) => {\n setInputValue('')\n setInputTokenString(newInputToken)\n }, [])\n\n const handleMaxButton = () => {\n const balance = new BigNumber(inputCurrencyBalance ?? '0')\n const principalDecimals = bondData?.lpToken?.decimals?.[bondData?.chainId] ?? 6\n const maxBuyAmount = getMaxBuy(bondData, SDKConfig.showLowValueBonds)\n\n if (!isZap) {\n const maxPossibleUserPurchase = getPayoutAmount(bondData, balance.toString(), '0')\n if (maxPossibleUserPurchase > maxBuyAmount.toNumber()) {\n const principalForMaxBuy = getPrincipalAmount(bondData, maxBuyAmount.toString(), '0')\n setInputValue(new BigNumber(principalForMaxBuy).toFixed(principalDecimals))\n } else {\n setInputValue(balance.toFixed(principalDecimals))\n }\n } else {\n const principalForMaxBuy = getPrincipalAmount(bondData, maxBuyAmount.toString(), '0')\n const principalForMaxBuyUSD = new BigNumber(principalForMaxBuy).times(bondData?.principalTokenPrice ?? 0)\n const maxBuyAmountInSelectedToken = principalForMaxBuyUSD.div(inputTokenPrice ?? 0)\n const decimals =\n enrichedTokenData?.token === 'NATIVE' ? 8 : (enrichedTokenData?.token.decimals[bondData?.chainId!] ?? 8)\n\n if (balance.gte(maxBuyAmountInSelectedToken)) {\n setInputValue(maxBuyAmountInSelectedToken.toFixed(decimals))\n } else {\n setInputValue(balance.toFixed(decimals))\n }\n }\n }\n\n const handleBuyCallback = async () => {\n if (!aptosAccount || !bondData || !inputValue) return\n track({\n event: 'buyBondClick',\n chain: bondChain,\n data: {\n cat: bondData?.billType,\n bond: bondData?.earnToken.symbol,\n value: parseFloat(inputValue) * (inputTokenPrice ?? 0),\n },\n })\n try {\n setLoadingTx(true)\n\n const principalDecimals = bondData.lpToken.decimals[bondData.chainId] ?? 6\n const atomicAmount = new BigNumber(inputValue)\n .times(new BigNumber(10).pow(principalDecimals))\n .integerValue(BigNumber.ROUND_FLOOR)\n .toFixed(0)\n\n const market = bondData.contractAddress[bondData.chainId] ?? ''\n\n // Read fresh pricing from the contract\n const marketInfo = await readAptosMarketInfo(market)\n const trueBillPriceU64 = marketInfo[17] // u64 scaled 1e8\n const atomicMaxPrice = new BigNumber(trueBillPriceU64)\n .times(new BigNumber(100 + slippage))\n .dividedBy(new BigNumber(100))\n .integerValue(BigNumber.ROUND_CEIL)\n .toFixed(0)\n\n const response = await signAndSubmitTransaction?.({\n data: {\n function: APTOS_DEPOSIT_FUNCTION,\n typeArguments: [],\n functionArguments: [market, atomicAmount, atomicMaxPrice, aptosAccount],\n },\n })\n if (!response?.hash) throw new Error('No tx hash returned by wallet')\n\n const aptos = getAptosClient()\n await aptos.waitForTransaction({ transactionHash: response.hash })\n // waitForTransaction may not include events — fetch full tx details separately\n const txDetails = await aptos.getTransactionByHash({ transactionHash: response.hash })\n const txnWithEvents = txDetails as unknown as { events?: Array<{ type: string; data: any }> }\n const depositEvent = extractDepositEvent(txnWithEvents)\n const newBillId = depositEvent?.bill_id ?? extractBillMinted(txnWithEvents)?.bill_id ?? ''\n\n track({\n event: 'bond',\n chain: bondChain,\n data: {\n cat: 'lp-buy',\n type: bondData?.billType ?? '',\n typedValue: inputValue,\n principalToken: bondData?.lpToken.symbol ?? '',\n earnToken: bondData?.earnToken.symbol ?? '',\n address: remove0xPrefix(market),\n usdAmount: parseFloat(inputValue) * (inputTokenPrice ?? 0),\n },\n })\n\n addToastSuccess(response.hash, bondChain as ChainId)\n setBillId?.(newBillId)\n } catch (error: any) {\n console.error('Error during Aptos bond purchase:', error)\n addToastError(error?.message || 'Unknown error')\n reportError({\n apiUrl: SDKConfig?.urls?.apiV2,\n error: error?.message,\n extraInfo: { type: 'aptosBuyBond', error: error?.message },\n chainId: bondChain,\n account: aptosAccount,\n })\n } finally {\n setLoadingTx(false)\n }\n }\n\n const handleZapCallback = async () => {\n if (loadingTx || !aptosAccount || !bondData || !panoraQuote || !signAndSubmitTransaction) return\n\n track({\n event: 'buyBondClick',\n chain: bondChain,\n data: {\n cat: bondData?.billType,\n bond: bondData?.earnToken.symbol,\n value: parseFloat(inputValue) * (inputTokenPrice ?? 0),\n },\n })\n\n try {\n setLoadingTx(true)\n const aptos = getAptosClient()\n\n // TX1: Execute Panora swap — the quote's txData contains the entry\n // function payload ready for the wallet adapter.\n const swapTxData = panoraQuote.txData\n if (!swapTxData || !swapTxData.function) {\n throw new Error('Panora quote missing txData')\n }\n\n const swapResponse = await signAndSubmitTransaction({\n data: swapTxData as any,\n })\n if (!swapResponse?.hash) throw new Error('No tx hash returned for swap')\n\n await aptos.waitForTransaction({ transactionHash: swapResponse.hash })\n\n // TX2: Deposit into bond with the swapped principal tokens.\n // Use the deposit amount from the quote (what we received from the swap).\n const principalDecimals = bondData.lpToken.decimals[bondData.chainId] ?? 6\n const depositAmountAtomic = new BigNumber(zapDepositAmount)\n .times(new BigNumber(10).pow(principalDecimals))\n .integerValue(BigNumber.ROUND_FLOOR)\n .toFixed(0)\n\n const market = bondData.contractAddress[bondData.chainId] ?? ''\n\n // Read fresh pricing\n const marketInfo = await readAptosMarketInfo(market)\n const trueBillPriceU64 = marketInfo[17]\n const atomicMaxPrice = new BigNumber(trueBillPriceU64)\n .times(new BigNumber(100 + slippage))\n .dividedBy(new BigNumber(100))\n .integerValue(BigNumber.ROUND_CEIL)\n .toFixed(0)\n\n const depositResponse = await signAndSubmitTransaction({\n data: {\n function: APTOS_DEPOSIT_FUNCTION,\n typeArguments: [],\n functionArguments: [market, depositAmountAtomic, atomicMaxPrice, aptosAccount],\n },\n })\n if (!depositResponse?.hash) throw new Error('No tx hash returned for deposit')\n\n await aptos.waitForTransaction({ transactionHash: depositResponse.hash })\n const txDetails = await aptos.getTransactionByHash({ transactionHash: depositResponse.hash })\n const txnWithEvents = txDetails as unknown as { events?: Array<{ type: string; data: any }> }\n const depositEvent = extractDepositEvent(txnWithEvents)\n const newBillId = depositEvent?.bill_id ?? extractBillMinted(txnWithEvents)?.bill_id ?? ''\n\n // Track zap events\n track({\n event: 'zap',\n chain: bondChain,\n data: {\n cat: 'bond',\n token1: getSymbol(inputToken),\n token2: bondData?.lpToken.symbol ?? '',\n amount: parseFloat(inputValue) * (inputTokenPrice ?? 0),\n },\n })\n\n track({\n event: 'bond',\n chain: bondChain,\n data: {\n cat: 'zap-buy-two-tx',\n type: bondData?.billType ?? '',\n typedValue: inputValue,\n principalToken: bondData?.lpToken.symbol ?? '',\n earnToken: bondData?.earnToken.symbol ?? '',\n address: remove0xPrefix(market),\n usdAmount: parseFloat(inputValue) * (inputTokenPrice ?? 0),\n },\n })\n\n addToastSuccess(depositResponse.hash, bondChain as ChainId)\n setBillId?.(newBillId)\n } catch (error: any) {\n console.error('Error during Aptos zap + bond purchase:', error)\n addToastError(error?.message || 'Unknown error during swap and bond')\n reportError({\n apiUrl: SDKConfig?.urls?.apiV2,\n error: error?.message,\n extraInfo: { type: 'aptosPanoraZapBuyBond', error: error?.message, quote: panoraQuote },\n chainId: bondChain,\n account: aptosAccount,\n })\n } finally {\n setLoadingTx(false)\n }\n }\n\n const handleBuy = () => {\n if (loadingTx) return\n if (isZap) {\n handleZapCallback()\n } else {\n handleBuyCallback()\n }\n }\n\n // Sync inputTokenString when bondData loads after initial render\n useEffect(() => {\n const addr = bondData?.lpToken?.address?.[bondData?.chainId]\n if (addr && !inputTokenString) {\n setInputTokenString(addr)\n }\n }, [bondData?.lpToken?.address, bondData?.chainId]) // eslint-disable-line react-hooks/exhaustive-deps\n\n // Auto-select highest balance token when zap list loads\n const [hasChecked, setHasChecked] = useState(false)\n useEffect(() => {\n if (zapListFetched && !hasChecked) {\n if (parseFloat(inputCurrencyBalance ?? '0') < 0.0001) {\n setInputTokenString(\n sortedZapList[0]?.token === 'NATIVE' ? 'NATIVE' : sortedZapList[0]?.token.address[bondChain as ChainId],\n )\n }\n setHasChecked(true)\n }\n /* eslint-disable react-hooks/exhaustive-deps */\n }, [inputCurrencyBalance, zapListFetched])\n\n const hasPositiveBonus = (trueBondPriceData?.bonusWithFee ?? 0) > 0\n\n const canBuy =\n !load &&\n !!aptosAccount &&\n !bondData?.soldOut &&\n !!inputValue &&\n parseFloat(inputValue) > 0 &&\n !exceedsRealMaxBuy &&\n !exceedsBalance &&\n hasPositiveBonus &&\n !SDKConfig.blockSales &&\n !zapError &&\n !(isZap && !panoraQuote)\n\n return bondData ? (\n <Flex className=\"modal-content\" sx={{ ...MCBuyComponentStyles[bondData?.marketingCampaign as MarketingCampaign] }}>\n <Flex className=\"modaltable-container\">\n <BondModalHeader bondData={bondData} onDismiss={onDismiss} hidePromotionUi />\n <ProjectDescription description={bondData.shortDescription} isProjectView />\n <Flex sx={{ width: '100%', display: isProjectView ? ['flex', 'flex', 'flex', 'none'] : 'flex' }}>\n <BondCards bondData={bondData} isDoingMaxBuy={exceedsSafeMaxBuy && !exceedsRealMaxBuy} />\n </Flex>\n <Estimations\n depositAmount={depositAmount}\n inputValue={inputValue}\n inputTokenPrice={inputTokenPrice}\n bondData={bondData}\n youSpendString={youSpendString}\n isZap={isZap}\n fetchingZapQuote={fetchingZapQuote}\n zapError={zapError}\n />\n <TokenSelectorPanel\n typedValue={inputValue}\n setTypedValue={setInputValue}\n selectedToken={inputToken}\n handleValueBtn={handleMaxButton}\n handleCurrencySelect={handleCurrencySelect}\n bondChainId={ChainId.APTOS}\n enableZap={true}\n bondPrincipalToken={bondData?.lpToken}\n tokenBalance={inputCurrencyBalance ?? undefined}\n selectedTokenPrice={inputTokenPrice}\n isConnected={!!aptosAccount}\n />\n {bondData?.warningCard && (\n <Flex\n sx={{\n width: '100%',\n background: '#DE62F366',\n justifyContent: 'center',\n mt: '10px',\n borderRadius: 'normal',\n p: '2px 10px',\n }}\n >\n <Text sx={{ fontSize: '12px', fontWeight: 400, display: 'flex', alignItems: 'center', gap: '10px' }}>\n <SafeHTMLComponent html={bondData?.warningCard} />\n </Text>\n </Flex>\n )}\n <Flex className=\"modaltable-container button-container\">\n <Flex className=\"button-container buy\">\n {!aptosAccount ? (\n <ConnectAptosWalletButton />\n ) : (\n <Button\n className=\"action-button\"\n load={load}\n disabled={!canBuy}\n onClick={handleBuy}\n sx={{ width: '100%', fontSize: ['14px', '14px', '14px', '16px'] }}\n >\n {SDKConfig.blockSales\n ? 'Complete KYC to Buy'\n : exceedsRealMaxBuy\n ? 'Exceeds Max Buy. Reduce amount'\n : exceedsBalance\n ? 'Insufficient balance'\n : zapError\n ? 'Swap quote failed'\n : !inputValue || parseFloat(inputValue) === 0\n ? 'Insert amount'\n : 'buy'}\n </Button>\n )}\n </Flex>\n </Flex>\n </Flex>\n </Flex>\n ) : (\n <></>\n )\n}\n\nexport default BuyComponentAptos\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
@@ -1,500 +0,0 @@
1
- import { jsx, jsxs, Fragment } from 'theme-ui/jsx-runtime';
2
- import { useState, useCallback, useEffect } from 'react';
3
- import BigNumber from 'bignumber.js';
4
- import { ChainId } from '@ape.swap/apeswap-lists';
5
- import { Transaction } from '@mysten/sui/transactions';
6
- import useSuiZapQuote, { AFTERMATH_TX_API_URL } from '../../state/zap/useSuiZapQuote.js';
7
- import { findSuiZapToken } from '../../config/constants/suiZapTokens.js';
8
- import useBondsData from '../../state/bonds/useBondsData.js';
9
- import { useSDKConfig } from '../../state/useSDKConfig.js';
10
- import { usePopups } from '../../state/popups/usePopups.js';
11
- import { useSlippage } from '../../state/slippage/useSlippage.js';
12
- import { formatUSDNumber, getMaxBuy, getPayoutAmount, getPrincipalAmount } from '../../utils/displayHelpers.js';
13
- import { formatNumberSI } from '../../utils/formatNumber.js';
14
- import { findHighestTrueBondPrice } from '../../utils/bondPriceHelpers.js';
15
- import { reportError } from '../../utils/reportError.js';
16
- import { MCBuyComponentStyles } from '../../utils/campaignStyles.js';
17
- import track from '../../utils/track.js';
18
- import { remove0xPrefix } from '../../utils/remove0xPrefix.js';
19
- import { getSymbol } from '../../utils/getNativeTicker.js';
20
- import useSUIAccount from '../../hooks/accounts/useSUIAccount.js';
21
- import useTokenFromZapList from '../../hooks/useTokenFromZapList.js';
22
- import useSortedZapList from '../../hooks/useSortedZapList.js';
23
- import TokenSelectorPanel from '../../components/TokenSelectorPanel/index.js';
24
- import BondModalHeader from './components/BondModalHeader.js';
25
- import BondCards from './components/BondCards/BondCards.js';
26
- import Estimations from './components/Estimations.js';
27
- import ProjectDescription from './components/ProjectDescription.js';
28
- import Flex from '../../components/uikit-sdk/Flex/index.js';
29
- import Text from '../../components/uikit-sdk/Text/index.js';
30
- import Button from '../../components/uikit-sdk/Button/Button.js';
31
- import SafeHTMLComponent from '../../components/SafeHTMLComponent/index.js';
32
- import { SUI_DEPOSIT_FUNCTION, SUI_PACKAGE_ID } from '../../constants/suiConstants.js';
33
- import { getSuiClient, readFreshTrueBondPrice, verifySuiTxSuccess } from '../../utils/suiHelpers.js';
34
- import { openSuiConnectModal } from '../../config/constants/suiCallbacks.js';
35
- import { useQueryClient } from '@tanstack/react-query';
36
- import { QUERY_KEYS } from '../../config/constants/queryKeys.js';
37
- import axios from 'axios';
38
-
39
- const extractSuiBillId = async (digest, suiClient) => {
40
- const txBlock = await suiClient.getTransactionBlock({
41
- digest,
42
- options: {
43
- showEffects: true,
44
- showObjectChanges: true,
45
- showEvents: true,
46
- },
47
- });
48
- const bondNftType = `${SUI_PACKAGE_ID}::bond_nft::BondNFT`;
49
- const createdNft = txBlock.objectChanges?.find((change) => change.type === 'created' && 'objectType' in change && change.objectType?.includes(bondNftType));
50
- if (createdNft && 'objectId' in createdNft) {
51
- const nftObjectId = createdNft.objectId;
52
- try {
53
- const nftObj = await suiClient.getObject({
54
- id: nftObjectId,
55
- options: { showContent: true },
56
- });
57
- if (nftObj.data?.content?.dataType === 'moveObject') {
58
- const fields = nftObj.data.content.fields;
59
- const billId = String(fields?.bill_id ?? '');
60
- if (billId && billId !== 'undefined' && billId !== '') {
61
- return billId;
62
- }
63
- }
64
- }
65
- catch (e) {
66
- console.warn('[SUI AFTER-PURCHASE] Failed to read BondNFT object:', nftObjectId, e);
67
- }
68
- }
69
- return `digest:${digest}`;
70
- };
71
- const BuyComponentSui = ({ onDismiss, bondAddress, bondChain, isProjectView, setBillId, }) => {
72
- const SDKConfig = useSDKConfig();
73
- const queryClient = useQueryClient();
74
- // Hooks
75
- const { address: suiAccount, signAndExecuteTransaction } = useSUIAccount();
76
- const { data: bonds } = useBondsData();
77
- const { addToastError, addToastSuccess } = usePopups();
78
- const { solSlippage: slippage } = useSlippage(); // reuse Sol slippage bucket for Sui
79
- const bondData = bonds?.find((bond) => bond?.contractAddress?.[bond?.chainId]?.toLowerCase() === bondAddress?.toLowerCase());
80
- // Derived pricing (same path the Solana no-tier branch uses).
81
- const trueBondPriceData = findHighestTrueBondPrice('0', bondData?.trueBondPrices);
82
- // State
83
- const [inputValue, setInputValue] = useState('');
84
- const [inputTokenString, setInputTokenString] = useState(bondData?.lpToken?.address?.[bondData?.chainId]);
85
- const [loadingTx, setLoadingTx] = useState(false);
86
- // Token selection — reuses the same infrastructure as Solana
87
- const inputToken = useTokenFromZapList(inputTokenString, bondData?.chainId, bondData?.lpToken);
88
- const principalAddress = bondData?.lpToken?.address?.[bondData?.chainId];
89
- // Detect zap: selected token differs from the bond principal
90
- const SUI_NATIVE_COIN_TYPE = '0x2::sui::SUI';
91
- const isNativeMatchingPrincipal = (inputTokenString === 'NATIVE' || inputTokenString?.toLowerCase() === SUI_NATIVE_COIN_TYPE.toLowerCase()) &&
92
- principalAddress?.toLowerCase() === SUI_NATIVE_COIN_TYPE.toLowerCase();
93
- const isZap = !!inputTokenString &&
94
- !!principalAddress &&
95
- !isNativeMatchingPrincipal &&
96
- inputTokenString.toLowerCase() !== principalAddress.toLowerCase();
97
- // Zap quote from Aftermath DEX aggregator
98
- const suiZapToken = findSuiZapToken(inputToken && inputToken !== 'NATIVE'
99
- ? inputToken?.address?.[ChainId.SUI]
100
- : inputToken === 'NATIVE'
101
- ? '0x2::sui::SUI'
102
- : undefined);
103
- const [fetchingZapQuote, aftermathQuote, zapDepositAmount, zapError] = useSuiZapQuote(inputValue, suiZapToken, bondData, suiAccount ?? undefined, slippage);
104
- // Sorted zap list (balances + prices)
105
- const { sortedZapList, isFetched: zapListFetched } = useSortedZapList(bondChain, bondData?.lpToken);
106
- const enrichedTokenData = sortedZapList.find((item) => item.token === 'NATIVE' || inputToken === 'NATIVE'
107
- ? item.token === inputToken
108
- : item?.token?.address?.[bondChain]?.toLowerCase() ===
109
- inputToken?.address?.[bondChain]?.toLowerCase());
110
- const inputCurrencyBalance = enrichedTokenData?.balance;
111
- const inputTokenPrice = enrichedTokenData?.price;
112
- // Estimations — use zapDepositAmount if swapping
113
- const depositAmount = isZap ? zapDepositAmount : inputValue;
114
- const youSpendString = `${formatNumberSI(inputValue)} ${getSymbol(inputToken, bondData?.chainId)} = $${formatUSDNumber((parseFloat(inputValue || '0') * (inputTokenPrice ?? 0)).toString())}`;
115
- const exceedsRealMaxBuy = getMaxBuy(bondData, true).lte(getPayoutAmount(bondData, depositAmount, '0'));
116
- const exceedsSafeMaxBuy = getMaxBuy(bondData, false)
117
- .times(isZap ? 0.995 : 0.9995)
118
- .lte(getPayoutAmount(bondData, depositAmount, '0'));
119
- const exceedsBalance = new BigNumber(inputCurrencyBalance ?? '0').lt(inputValue);
120
- const load = loadingTx || (fetchingZapQuote && !!inputValue);
121
- // Handlers
122
- const handleCurrencySelect = useCallback((newInputToken) => {
123
- setInputValue('');
124
- setInputTokenString(newInputToken);
125
- }, []);
126
- const handleMaxButton = () => {
127
- const balance = new BigNumber(inputCurrencyBalance ?? '0');
128
- const principalDecimals = bondData?.lpToken?.decimals?.[bondData?.chainId] ?? 9;
129
- const maxBuyAmount = getMaxBuy(bondData, SDKConfig.showLowValueBonds);
130
- const maxPossibleUserPurchase = getPayoutAmount(bondData, balance.toString(), '0');
131
- if (maxPossibleUserPurchase > maxBuyAmount.toNumber()) {
132
- const principalForMaxBuy = getPrincipalAmount(bondData, maxBuyAmount.toString(), '0');
133
- setInputValue(new BigNumber(principalForMaxBuy).toFixed(principalDecimals));
134
- }
135
- else {
136
- setInputValue(balance.toFixed(principalDecimals));
137
- }
138
- };
139
- const handleBuyCallback = async () => {
140
- if (!suiAccount || !bondData || !inputValue || !signAndExecuteTransaction)
141
- return;
142
- track({
143
- event: 'buyBondClick',
144
- chain: bondChain,
145
- data: {
146
- cat: bondData?.billType,
147
- bond: bondData?.earnToken.symbol,
148
- value: parseFloat(inputValue) * (inputTokenPrice ?? 0),
149
- },
150
- });
151
- try {
152
- setLoadingTx(true);
153
- const principalDecimals = bondData.lpToken.decimals[bondData.chainId] ?? 9;
154
- const atomicAmount = new BigNumber(inputValue)
155
- .times(new BigNumber(10).pow(principalDecimals))
156
- .integerValue(BigNumber.ROUND_FLOOR)
157
- .toFixed(0);
158
- const market = bondData.contractAddress[bondData.chainId];
159
- // Read fresh bond price from chain to avoid stale cache after previous purchases
160
- const freshTruePrice = await readFreshTrueBondPrice(market);
161
- const atomicMaxPrice = new BigNumber(freshTruePrice.toString())
162
- .times(new BigNumber(100 + slippage))
163
- .dividedBy(new BigNumber(100))
164
- .integerValue(BigNumber.ROUND_CEIL)
165
- .toFixed(0);
166
- const principalCoinType = bondData.lpToken.address[bondData.chainId];
167
- const payoutCoinType = bondData.earnToken.address[bondData.chainId];
168
- if (!principalCoinType || !payoutCoinType)
169
- throw new Error('Missing token type info');
170
- // Build Sui transaction
171
- const tx = new Transaction();
172
- const isPrincipalNativeSui = !principalCoinType || principalCoinType.toLowerCase() === SUI_NATIVE_COIN_TYPE.toLowerCase();
173
- let principalCoin;
174
- if (isPrincipalNativeSui) {
175
- ;
176
- [principalCoin] = tx.splitCoins(tx.gas, [tx.pure.u64(atomicAmount)]);
177
- }
178
- else {
179
- const suiClient = getSuiClient();
180
- const userCoins = await suiClient.getCoins({ owner: suiAccount, coinType: principalCoinType });
181
- if (!userCoins.data.length)
182
- throw new Error(`No ${bondData.lpToken.symbol} coins found in wallet`);
183
- if (userCoins.data.length > 1) {
184
- const [primary, ...rest] = userCoins.data.map((c) => tx.object(c.coinObjectId));
185
- tx.mergeCoins(primary, rest);
186
- [principalCoin] = tx.splitCoins(primary, [tx.pure.u64(atomicAmount)]);
187
- }
188
- else {
189
- ;
190
- [principalCoin] = tx.splitCoins(tx.object(userCoins.data[0].coinObjectId), [tx.pure.u64(atomicAmount)]);
191
- }
192
- }
193
- if (!market || !bondData?.suiTreasuryId || !bondData?.billNnftAddress?.[ChainId.SUI]) {
194
- return;
195
- }
196
- tx.moveCall({
197
- target: SUI_DEPOSIT_FUNCTION,
198
- typeArguments: [payoutCoinType, principalCoinType],
199
- arguments: [
200
- tx.object(market),
201
- tx.object(bondData.suiTreasuryId),
202
- tx.object(bondData.billNnftAddress[ChainId.SUI]),
203
- principalCoin,
204
- tx.pure.u64(atomicMaxPrice),
205
- tx.pure.address(suiAccount),
206
- tx.object('0x6'), // clock
207
- ],
208
- });
209
- // Pre-build the transaction so the wallet receives fully-resolved bytes.
210
- // Some wallets (e.g. Phantom) fail with "Unexpected error" when they have
211
- // to build/simulate a Transaction object themselves.
212
- tx.setSender(suiAccount);
213
- tx.setGasBudget(50000000); // 0.05 SUI — generous for a bond deposit
214
- const builtBytes = await tx.build({ client: getSuiClient() });
215
- const prebuiltTx = Transaction.from(builtBytes);
216
- const response = await signAndExecuteTransaction({
217
- transaction: prebuiltTx,
218
- });
219
- const digest = response?.digest;
220
- if (!digest)
221
- throw new Error('No tx digest returned by wallet');
222
- const suiClient = getSuiClient();
223
- await suiClient.waitForTransaction({ digest });
224
- await verifySuiTxSuccess(digest);
225
- // Extract the bill_id from the confirmed transaction.
226
- // extractSuiBillId logs the full tx block so you can inspect the raw data
227
- // in case automatic extraction fails.
228
- const billId = await extractSuiBillId(digest, suiClient);
229
- console.log('[SUI AFTER-PURCHASE] handleBuyCallback billId:', billId);
230
- // Invalidate bonds data so next purchase uses fresh pricing
231
- await queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.BONDS_DATA] });
232
- // Sui's indexer has a short lag — getOwnedObjects may not return the
233
- // new BondNFT immediately. Schedule re-invalidations so the Your Bonds
234
- // view picks up the new bond once the indexer catches up.
235
- setTimeout(() => queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.USER_BONDS] }), 3000);
236
- track({
237
- event: 'bond',
238
- chain: bondChain,
239
- data: {
240
- cat: 'lp-buy',
241
- type: bondData?.billType ?? '',
242
- typedValue: inputValue,
243
- principalToken: bondData?.lpToken.symbol ?? '',
244
- earnToken: bondData?.earnToken.symbol ?? '',
245
- address: remove0xPrefix(market),
246
- usdAmount: parseFloat(inputValue) * (inputTokenPrice ?? 0),
247
- },
248
- });
249
- addToastSuccess(digest, bondChain);
250
- setBillId?.(billId);
251
- }
252
- catch (error) {
253
- console.error('[SUI DEBUG] Error during Sui bond purchase:', error);
254
- addToastError(error?.message || 'Unknown error');
255
- reportError({
256
- apiUrl: SDKConfig?.urls?.apiV2,
257
- error: error?.message,
258
- extraInfo: { type: 'suiBuyBond', error: error?.message },
259
- chainId: bondChain,
260
- account: suiAccount,
261
- });
262
- }
263
- finally {
264
- setLoadingTx(false);
265
- }
266
- };
267
- const handleZapCallback = async () => {
268
- if (loadingTx || !suiAccount || !bondData || !aftermathQuote || !signAndExecuteTransaction)
269
- return;
270
- track({
271
- event: 'buyBondClick',
272
- chain: bondChain,
273
- data: {
274
- cat: bondData?.billType,
275
- bond: bondData?.earnToken.symbol,
276
- value: parseFloat(inputValue) * (inputTokenPrice ?? 0),
277
- },
278
- });
279
- try {
280
- setLoadingTx(true);
281
- const suiClient = getSuiClient();
282
- const principalDecimals = bondData.lpToken.decimals[bondData.chainId] ?? 6;
283
- const depositAmountAtomic = new BigNumber(zapDepositAmount)
284
- .times(new BigNumber(10).pow(principalDecimals))
285
- .integerValue(BigNumber.ROUND_FLOOR)
286
- .toFixed(0);
287
- // TX1: Acquire principal tokens
288
- // if (IS_SUI_MAINNET) {
289
- // Mainnet: swap via Aftermath DEX aggregator
290
- const txResponse = await axios.post(AFTERMATH_TX_API_URL, {
291
- walletAddress: suiAccount,
292
- completeRoute: aftermathQuote,
293
- slippage: slippage / 100,
294
- });
295
- const swapTxBytes = txResponse.data;
296
- if (!swapTxBytes)
297
- throw new Error('Aftermath returned no transaction data');
298
- const swapTx = Transaction.from(swapTxBytes);
299
- const swapResponse = await signAndExecuteTransaction({ transaction: swapTx });
300
- const swapDigest = swapResponse?.digest;
301
- if (!swapDigest)
302
- throw new Error('No tx digest returned for swap');
303
- await suiClient.waitForTransaction({ digest: swapDigest });
304
- // } else {
305
- // // Testnet: mint principal tokens via test_principal_token::mint
306
- // // No DEX aggregator supports Sui testnet or custom test tokens.
307
- // const mintTx = new Transaction()
308
- // mintTx.moveCall({
309
- // target: SUI_MINT_PRINCIPAL_FUNCTION,
310
- // arguments: [
311
- // mintTx.object(SUI_PRINCIPAL_TOKEN_ADMIN_TESTNET),
312
- // mintTx.pure.u64(depositAmountAtomic),
313
- // mintTx.pure.address(suiAccount),
314
- // ],
315
- // })
316
- //
317
- // mintTx.setSender(suiAccount)
318
- // mintTx.setGasBudget(50_000_000)
319
- // const builtMint = await mintTx.build({ client: suiClient })
320
- // const prebuiltMint = Transaction.from(builtMint)
321
- //
322
- // const mintResponse = await signAndExecuteTransaction({ transaction: prebuiltMint })
323
- // const mintDigest = mintResponse?.digest
324
- // if (!mintDigest) throw new Error('No tx digest returned for testnet mint')
325
- // await suiClient.waitForTransaction({ digest: mintDigest })
326
- // }
327
- // TX2: Deposit into bond with principal tokens
328
- const market = bondData.contractAddress[ChainId.SUI];
329
- // Read fresh bond price from chain to avoid stale cache
330
- const freshTruePrice = await readFreshTrueBondPrice(market);
331
- const atomicMaxPrice = new BigNumber(freshTruePrice.toString())
332
- .times(new BigNumber(100 + slippage))
333
- .dividedBy(new BigNumber(100))
334
- .integerValue(BigNumber.ROUND_CEIL)
335
- .toFixed(0);
336
- const principalCoinType = bondData.lpToken.address[bondData.chainId];
337
- const payoutCoinType = bondData.earnToken.address[bondData.chainId];
338
- if (!principalCoinType || !payoutCoinType)
339
- throw new Error('Missing token type info');
340
- const tx = new Transaction();
341
- const isPrincipalNativeSui = principalCoinType.toLowerCase() === SUI_NATIVE_COIN_TYPE.toLowerCase();
342
- let principalCoin;
343
- if (isPrincipalNativeSui) {
344
- ;
345
- [principalCoin] = tx.splitCoins(tx.gas, [tx.pure.u64(depositAmountAtomic)]);
346
- }
347
- else {
348
- const userCoins = await suiClient.getCoins({ owner: suiAccount, coinType: principalCoinType });
349
- if (!userCoins.data.length)
350
- throw new Error(`No ${bondData.lpToken.symbol} coins found after swap`);
351
- if (userCoins.data.length > 1) {
352
- const [primary, ...rest] = userCoins.data.map((c) => tx.object(c.coinObjectId));
353
- tx.mergeCoins(primary, rest);
354
- [principalCoin] = tx.splitCoins(primary, [tx.pure.u64(depositAmountAtomic)]);
355
- }
356
- else {
357
- ;
358
- [principalCoin] = tx.splitCoins(tx.object(userCoins.data[0].coinObjectId), [
359
- tx.pure.u64(depositAmountAtomic),
360
- ]);
361
- }
362
- }
363
- if (!market || !bondData?.suiTreasuryId || !bondData?.billNnftAddress?.[ChainId.SUI]) {
364
- return;
365
- }
366
- tx.moveCall({
367
- target: SUI_DEPOSIT_FUNCTION,
368
- typeArguments: [payoutCoinType, principalCoinType],
369
- arguments: [
370
- tx.object(market),
371
- tx.object(bondData.suiTreasuryId),
372
- tx.object(bondData.billNnftAddress[ChainId.SUI]),
373
- principalCoin,
374
- tx.pure.u64(atomicMaxPrice),
375
- tx.pure.address(suiAccount),
376
- tx.object('0x6'), // clock
377
- ],
378
- });
379
- tx.setSender(suiAccount);
380
- tx.setGasBudget(50000000);
381
- const builtDeposit = await tx.build({ client: suiClient });
382
- const prebuiltDeposit = Transaction.from(builtDeposit);
383
- const depositResponse = await signAndExecuteTransaction({ transaction: prebuiltDeposit });
384
- const depositDigest = depositResponse?.digest;
385
- if (!depositDigest)
386
- throw new Error('No tx digest returned for deposit');
387
- await suiClient.waitForTransaction({ digest: depositDigest });
388
- await verifySuiTxSuccess(depositDigest);
389
- // Extract the bill_id from the confirmed deposit transaction.
390
- // extractSuiBillId logs the full tx block so you can inspect the raw data
391
- // in case automatic extraction fails.
392
- const billId = await extractSuiBillId(depositDigest, suiClient);
393
- console.log('[SUI AFTER-PURCHASE] handleZapCallback billId:', billId);
394
- // Invalidate bonds data so next purchase uses fresh pricing
395
- await queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.BONDS_DATA] });
396
- // Sui indexer lag — schedule delayed re-invalidations for user bonds
397
- setTimeout(() => queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.USER_BONDS] }), 3000);
398
- track({
399
- event: 'zap',
400
- chain: bondChain,
401
- data: {
402
- cat: 'bond',
403
- token1: getSymbol(inputToken, bondData?.chainId),
404
- token2: bondData?.lpToken.symbol ?? '',
405
- amount: parseFloat(inputValue) * (inputTokenPrice ?? 0),
406
- },
407
- });
408
- track({
409
- event: 'bond',
410
- chain: bondChain,
411
- data: {
412
- cat: 'lp-buy',
413
- type: bondData?.billType ?? '',
414
- typedValue: inputValue,
415
- principalToken: bondData?.lpToken.symbol ?? '',
416
- earnToken: bondData?.earnToken.symbol ?? '',
417
- address: remove0xPrefix(market),
418
- usdAmount: parseFloat(inputValue) * (inputTokenPrice ?? 0),
419
- },
420
- });
421
- addToastSuccess(depositDigest, bondChain);
422
- setBillId?.(billId);
423
- }
424
- catch (error) {
425
- console.error('Error during Sui zap bond purchase:', error);
426
- addToastError(error?.message || 'Unknown error');
427
- reportError({
428
- apiUrl: SDKConfig?.urls?.apiV2,
429
- error: error?.message,
430
- extraInfo: { type: 'suiZapBuyBond', error: error?.message },
431
- chainId: bondChain,
432
- account: suiAccount,
433
- });
434
- }
435
- finally {
436
- setLoadingTx(false);
437
- }
438
- };
439
- const handleBuy = () => {
440
- if (loadingTx)
441
- return;
442
- if (isZap) {
443
- handleZapCallback();
444
- }
445
- else {
446
- handleBuyCallback();
447
- }
448
- };
449
- // Sync inputTokenString when bondData loads after initial render
450
- useEffect(() => {
451
- const addr = bondData?.lpToken?.address?.[bondData?.chainId];
452
- if (addr && !inputTokenString) {
453
- setInputTokenString(addr);
454
- }
455
- }, [bondData?.lpToken?.address, bondData?.chainId]); // eslint-disable-line react-hooks/exhaustive-deps
456
- // Auto-select highest balance token when zap list loads
457
- const [hasChecked, setHasChecked] = useState(false);
458
- useEffect(() => {
459
- if (zapListFetched && !hasChecked) {
460
- if (parseFloat(inputCurrencyBalance ?? '0') < 0.0001) {
461
- setInputTokenString(sortedZapList[0]?.token === 'NATIVE' ? 'NATIVE' : sortedZapList[0]?.token.address[bondChain]);
462
- }
463
- setHasChecked(true);
464
- }
465
- /* eslint-disable react-hooks/exhaustive-deps */
466
- }, [inputCurrencyBalance, zapListFetched]);
467
- const hasPositiveBonus = (trueBondPriceData?.bonusWithFee ?? 0) > 0;
468
- const canBuy = !load &&
469
- !!suiAccount &&
470
- !bondData?.soldOut &&
471
- !!inputValue &&
472
- parseFloat(inputValue) > 0 &&
473
- !exceedsRealMaxBuy &&
474
- !exceedsBalance &&
475
- hasPositiveBonus &&
476
- !SDKConfig.blockSales &&
477
- !zapError &&
478
- !(isZap && !aftermathQuote);
479
- return bondData ? (jsx(Flex, { className: "modal-content", sx: { ...MCBuyComponentStyles[bondData?.marketingCampaign] }, children: jsxs(Flex, { className: "modaltable-container", children: [jsx(BondModalHeader, { bondData: bondData, onDismiss: onDismiss, hidePromotionUi: true }), jsx(ProjectDescription, { description: bondData.shortDescription, isProjectView: true }), jsx(Flex, { sx: { width: '100%', display: isProjectView ? ['flex', 'flex', 'flex', 'none'] : 'flex' }, children: jsx(BondCards, { bondData: bondData, isDoingMaxBuy: exceedsSafeMaxBuy && !exceedsRealMaxBuy }) }), jsx(Estimations, { depositAmount: depositAmount, inputValue: inputValue, inputTokenPrice: inputTokenPrice, bondData: bondData, youSpendString: youSpendString, isZap: isZap, fetchingZapQuote: fetchingZapQuote, zapError: zapError }), jsx(TokenSelectorPanel, { typedValue: inputValue, setTypedValue: setInputValue, selectedToken: inputToken, handleValueBtn: handleMaxButton, handleCurrencySelect: handleCurrencySelect, bondChainId: ChainId.SUI, enableZap: true, bondPrincipalToken: bondData?.lpToken, tokenBalance: inputCurrencyBalance ?? undefined, selectedTokenPrice: inputTokenPrice, isConnected: !!suiAccount }), bondData?.warningCard && (jsx(Flex, { sx: {
480
- width: '100%',
481
- background: '#DE62F366',
482
- justifyContent: 'center',
483
- mt: '10px',
484
- borderRadius: 'normal',
485
- p: '2px 10px',
486
- }, children: jsx(Text, { sx: { fontSize: '12px', fontWeight: 400, display: 'flex', alignItems: 'center', gap: '10px' }, children: jsx(SafeHTMLComponent, { html: bondData?.warningCard }) }) })), jsx(Flex, { className: "modaltable-container button-container", children: jsx(Flex, { className: "button-container buy", children: !suiAccount ? (jsx(Button, { className: "action-button", onClick: openSuiConnectModal, sx: { width: '100%', fontSize: ['14px', '14px', '14px', '16px'] }, children: "Connect to Sui" })) : (jsx(Button, { className: "action-button", load: load, disabled: !canBuy, onClick: handleBuy, sx: { width: '100%', fontSize: ['14px', '14px', '14px', '16px'] }, children: SDKConfig.blockSales
487
- ? 'Complete KYC to Buy'
488
- : zapError
489
- ? 'Swap quote failed'
490
- : exceedsRealMaxBuy
491
- ? 'Exceeds Max Buy. Reduce amount'
492
- : exceedsBalance
493
- ? 'Insufficient balance'
494
- : !inputValue || parseFloat(inputValue) === 0
495
- ? 'Insert amount'
496
- : 'buy' })) }) })] }) })) : (jsx(Fragment, {}));
497
- };
498
-
499
- export { BuyComponentSui as default };
500
- //# sourceMappingURL=BuyComponentSui.js.map