@ape.swap/bonds-sdk 5.1.48 → 5.1.49-test-0
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.
- package/README.md +14 -7
- package/dist/components/ConnectAptosWalletButton/ConnectAptosWalletButton.d.ts +4 -0
- package/dist/components/ConnectAptosWalletButton/ConnectAptosWalletButton.js +39 -0
- package/dist/components/ConnectAptosWalletButton/ConnectAptosWalletButton.js.map +1 -0
- package/dist/components/ConnectSuiWalletButton/ConnectSuiWalletButton.d.ts +5 -0
- package/dist/components/ConnectoToVmBanners/ConnectToAptosBanner.d.ts +1 -0
- package/dist/components/ConnectoToVmBanners/ConnectToAptosBanner.js +49 -0
- package/dist/components/ConnectoToVmBanners/ConnectToAptosBanner.js.map +1 -0
- package/dist/components/ConnectoToVmBanners/ConnectToEvmBanner.js +11 -15
- package/dist/components/ConnectoToVmBanners/ConnectToEvmBanner.js.map +1 -1
- package/dist/components/ConnectoToVmBanners/ConnectToSolanaBanner.js +13 -17
- package/dist/components/ConnectoToVmBanners/ConnectToSolanaBanner.js.map +1 -1
- package/dist/components/ConnectoToVmBanners/ConnectToSuiBanner.d.ts +1 -0
- package/dist/components/ConnectoToVmBanners/ConnectToSuiBanner.js +44 -0
- package/dist/components/ConnectoToVmBanners/ConnectToSuiBanner.js.map +1 -0
- package/dist/components/TokenInfoAndName/index.js +2 -0
- package/dist/components/TokenInfoAndName/index.js.map +1 -1
- package/dist/components/TokenSelectorPanel/index.js +11 -1
- package/dist/components/TokenSelectorPanel/index.js.map +1 -1
- package/dist/components/Tooltip/Tooltip.js +11 -3
- package/dist/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/components/uikit-sdk/Svg/index.js +6 -0
- package/dist/components/uikit-sdk/Svg/index.js.map +1 -1
- package/dist/components/uikit-sdk/Svg/tokens/APTOS.d.ts +4 -0
- package/dist/components/uikit-sdk/Svg/tokens/APTOS.js +8 -0
- package/dist/components/uikit-sdk/Svg/tokens/APTOS.js.map +1 -0
- package/dist/components/uikit-sdk/Svg/tokens/SUI.d.ts +4 -0
- package/dist/components/uikit-sdk/Svg/tokens/SUI.js +8 -0
- package/dist/components/uikit-sdk/Svg/tokens/SUI.js.map +1 -0
- package/dist/components/uikit-sdk/Svg/types.d.ts +2 -0
- package/dist/components/uikit-sdk/Svg/types.js +2 -0
- package/dist/components/uikit-sdk/Svg/types.js.map +1 -1
- package/dist/components/uikit-sdk/TokenImage/index.js +15 -3
- package/dist/components/uikit-sdk/TokenImage/index.js.map +1 -1
- package/dist/config/constants/addresses.d.ts +1 -1
- package/dist/config/constants/addresses.js +2 -0
- package/dist/config/constants/addresses.js.map +1 -1
- package/dist/config/constants/aptosZapTokens.d.ts +23 -0
- package/dist/config/constants/aptosZapTokens.js +66 -0
- package/dist/config/constants/aptosZapTokens.js.map +1 -0
- package/dist/config/constants/chains.d.ts +3 -1
- package/dist/config/constants/chains.js +12 -0
- package/dist/config/constants/chains.js.map +1 -1
- package/dist/config/constants/networks.js +9 -0
- package/dist/config/constants/networks.js.map +1 -1
- package/dist/config/constants/queryKeys.js +23 -1
- package/dist/config/constants/queryKeys.js.map +1 -1
- package/dist/config/constants/suiZapTokens.d.ts +14 -0
- package/dist/config/constants/suiZapTokens.js +41 -0
- package/dist/config/constants/suiZapTokens.js.map +1 -0
- package/dist/config/constants/tokens.js +48 -0
- package/dist/config/constants/tokens.js.map +1 -0
- package/dist/config/constants/variables.d.ts +1 -1
- package/dist/config/constants/variables.js +2 -0
- package/dist/config/constants/variables.js.map +1 -1
- package/dist/constants/aptosConstants.d.ts +20 -0
- package/dist/constants/aptosConstants.js +78 -0
- package/dist/constants/aptosConstants.js.map +1 -0
- package/dist/constants/suiConstants.d.ts +18 -0
- package/dist/constants/suiConstants.js +61 -0
- package/dist/constants/suiConstants.js.map +1 -0
- package/dist/hooks/accounts/useAPTAccount.d.ts +30 -0
- package/dist/hooks/accounts/useAPTAccount.js +39 -0
- package/dist/hooks/accounts/useAPTAccount.js.map +1 -0
- package/dist/hooks/accounts/useSUIAccount.d.ts +7 -0
- package/dist/hooks/accounts/useSUIAccount.js +46 -0
- package/dist/hooks/accounts/useSUIAccount.js.map +1 -0
- package/dist/hooks/useMonitorTx.d.ts +2 -21
- package/dist/hooks/useMonitorTx.js.map +1 -1
- package/dist/hooks/useSortedZapList.js +7 -2
- package/dist/hooks/useSortedZapList.js.map +1 -1
- package/dist/hooks/useTokenFromZapList.js +1 -0
- package/dist/hooks/useTokenFromZapList.js.map +1 -1
- package/dist/providers/AptosWalletProvider.d.ts +5 -0
- package/dist/providers/SuiWalletProvider.d.ts +5 -0
- package/dist/state/balance/useCurrencyBalance.js +9 -0
- package/dist/state/balance/useCurrencyBalance.js.map +1 -1
- package/dist/state/balance/useCurrencyBalanceAptos.d.ts +14 -0
- package/dist/state/balance/useCurrencyBalanceAptos.js +75 -0
- package/dist/state/balance/useCurrencyBalanceAptos.js.map +1 -0
- package/dist/state/balance/useCurrencyBalanceSui.d.ts +14 -0
- package/dist/state/balance/useCurrencyBalanceSui.js +42 -0
- package/dist/state/balance/useCurrencyBalanceSui.js.map +1 -0
- package/dist/state/balance/useUserTokensBalance.js +19 -1
- package/dist/state/balance/useUserTokensBalance.js.map +1 -1
- package/dist/state/bonds/aptosBondsConfig.d.ts +4 -0
- package/dist/state/bonds/aptosBondsConfig.js +114 -0
- package/dist/state/bonds/aptosBondsConfig.js.map +1 -0
- package/dist/state/bonds/fetchBillsUserAptos.d.ts +4 -0
- package/dist/state/bonds/fetchBillsUserAptos.js +187 -0
- package/dist/state/bonds/fetchBillsUserAptos.js.map +1 -0
- package/dist/state/bonds/fetchBillsUserSui.d.ts +4 -0
- package/dist/state/bonds/fetchBillsUserSui.js +287 -0
- package/dist/state/bonds/fetchBillsUserSui.js.map +1 -0
- package/dist/state/bonds/fetchBondsDataAptos.d.ts +12 -0
- package/dist/state/bonds/fetchBondsDataAptos.js +114 -0
- package/dist/state/bonds/fetchBondsDataAptos.js.map +1 -0
- package/dist/state/bonds/fetchBondsDataSui.d.ts +13 -0
- package/dist/state/bonds/fetchBondsDataSui.js +205 -0
- package/dist/state/bonds/fetchBondsDataSui.js.map +1 -0
- package/dist/state/bonds/suiBondsConfig.d.ts +4 -0
- package/dist/state/bonds/suiBondsConfig.js +113 -0
- package/dist/state/bonds/suiBondsConfig.js.map +1 -0
- package/dist/state/bonds/useBondsData.js +32 -8
- package/dist/state/bonds/useBondsData.js.map +1 -1
- package/dist/state/bonds/useBondsList.js +15 -2
- package/dist/state/bonds/useBondsList.js.map +1 -1
- package/dist/state/bonds/useUserBonds.d.ts +1 -1
- package/dist/state/bonds/useUserBonds.js +34 -12
- package/dist/state/bonds/useUserBonds.js.map +1 -1
- package/dist/state/bonds/utils.js +8 -0
- package/dist/state/bonds/utils.js.map +1 -1
- package/dist/state/price/useCurrencyPrice.js +2 -1
- package/dist/state/price/useCurrencyPrice.js.map +1 -1
- package/dist/state/tiers/useTierPoints.js +1 -4
- package/dist/state/tiers/useTierPoints.js.map +1 -1
- package/dist/state/tokenPrices/useTokenPrices.js +16 -1
- package/dist/state/tokenPrices/useTokenPrices.js.map +1 -1
- package/dist/state/useSDKConfig.d.ts +4 -0
- package/dist/state/useSDKConfig.js.map +1 -1
- package/dist/state/zap/useAptosZapQuote.d.ts +28 -0
- package/dist/state/zap/useAptosZapQuote.js +83 -0
- package/dist/state/zap/useAptosZapQuote.js.map +1 -0
- package/dist/state/zap/useSoulZapBondQuote.js +1 -0
- package/dist/state/zap/useSoulZapBondQuote.js.map +1 -1
- package/dist/state/zap/useSuiZapQuote.d.ts +24 -0
- package/dist/state/zap/useSuiZapQuote.js +119 -0
- package/dist/state/zap/useSuiZapQuote.js.map +1 -0
- package/dist/types/aptosBonds.d.ts +152 -0
- package/dist/types/yourbonds.d.ts +3 -9
- package/dist/utils/aptosHelpers.d.ts +80 -0
- package/dist/utils/aptosHelpers.js +202 -0
- package/dist/utils/aptosHelpers.js.map +1 -0
- package/dist/utils/getNativeTicker.js +1 -0
- package/dist/utils/getNativeTicker.js.map +1 -1
- package/dist/utils/suiHelpers.d.ts +6 -0
- package/dist/utils/suiHelpers.js +106 -0
- package/dist/utils/suiHelpers.js.map +1 -0
- package/dist/views/Bonds/components/BondRows/ActiveBondRows.js +8 -2
- package/dist/views/Bonds/components/BondRows/ActiveBondRows.js.map +1 -1
- package/dist/views/Bonds/components/BondRows/ModalHandler.js +18 -1
- package/dist/views/Bonds/components/BondRows/ModalHandler.js.map +1 -1
- package/dist/views/Bonds/components/ChainBanner/ChainBanner.js +29 -0
- package/dist/views/Bonds/components/ChainBanner/ChainBanner.js.map +1 -1
- package/dist/views/BuyBond/BuyBondModal.js +4 -1
- package/dist/views/BuyBond/BuyBondModal.js.map +1 -1
- package/dist/views/BuyBond/BuyComponentAptos.d.ts +10 -0
- package/dist/views/BuyBond/BuyComponentAptos.js +349 -0
- package/dist/views/BuyBond/BuyComponentAptos.js.map +1 -0
- package/dist/views/BuyBond/BuyComponentSui.d.ts +10 -0
- package/dist/views/BuyBond/BuyComponentSui.js +459 -0
- package/dist/views/BuyBond/BuyComponentSui.js.map +1 -0
- package/dist/views/BuyBond/components/Estimations.js +2 -1
- package/dist/views/BuyBond/components/Estimations.js.map +1 -1
- package/dist/views/BuyBond/components/PointsLeftForNextTier/PointsLeftForNextTier.js +8 -23
- package/dist/views/BuyBond/components/PointsLeftForNextTier/PointsLeftForNextTier.js.map +1 -1
- package/dist/views/YourBonds/YourBonds.js +19 -2
- package/dist/views/YourBonds/YourBonds.js.map +1 -1
- package/dist/views/YourBonds/components/ClaimAll/ClaimAllModal.js +139 -5
- package/dist/views/YourBonds/components/ClaimAll/ClaimAllModal.js.map +1 -1
- package/dist/views/YourBonds/components/ClaimAll/index.js +6 -2
- package/dist/views/YourBonds/components/ClaimAll/index.js.map +1 -1
- package/dist/views/YourBonds/components/UserBondRow/UserBondRowAptos.d.ts +6 -0
- package/dist/views/YourBonds/components/UserBondRow/UserBondRowAptos.js +109 -0
- package/dist/views/YourBonds/components/UserBondRow/UserBondRowAptos.js.map +1 -0
- package/dist/views/YourBonds/components/UserBondRow/UserBondRowSui.d.ts +6 -0
- package/dist/views/YourBonds/components/UserBondRow/UserBondRowSui.js +126 -0
- package/dist/views/YourBonds/components/UserBondRow/UserBondRowSui.js.map +1 -0
- package/dist/views/YourBonds/components/UserBondRow/index.d.ts +2 -0
- package/dist/views/YourBondsModal/YourBondsModal.js +3 -1
- package/dist/views/YourBondsModal/YourBondsModal.js.map +1 -1
- package/dist/views/YourBondsModal/components/Actions/ActionsAptos.d.ts +6 -0
- package/dist/views/YourBondsModal/components/Actions/ActionsAptos.js +96 -0
- package/dist/views/YourBondsModal/components/Actions/ActionsAptos.js.map +1 -0
- package/dist/views/YourBondsModal/components/Actions/ActionsSui.d.ts +6 -0
- package/dist/views/YourBondsModal/components/Actions/ActionsSui.js +115 -0
- package/dist/views/YourBondsModal/components/Actions/ActionsSui.js.map +1 -0
- package/dist/views/YourBondsModal/components/TransferBondModal/TransferActionAptos.d.ts +8 -0
- package/dist/views/YourBondsModal/components/TransferBondModal/TransferActionAptos.js +18 -0
- package/dist/views/YourBondsModal/components/TransferBondModal/TransferActionAptos.js.map +1 -0
- package/dist/views/YourBondsModal/components/TransferBondModal/index.js +2 -1
- package/dist/views/YourBondsModal/components/TransferBondModal/index.js.map +1 -1
- package/package.json +7 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetchBillsUserSui.js","sources":["../../../src/state/bonds/fetchBillsUserSui.ts"],"sourcesContent":["// =============================================================================\n// fetchUserOwnedSuiBonds — user bills fetcher for the Sui chain\n// =============================================================================\n//\n// On-chain first: reads user bills directly from Sui objects (no api-v2\n// dependency). Uses:\n//\n// getOwnedObjects(user, BondNFT filter) → [BondNFT objects]\n// Each BondNFT has fields: bill_id, bond_market, uri\n// getDynamicFieldObject(market.bills, bill_id) → Bill struct\n// Bill fields: payout, payout_claimed, vesting_term, vesting_start_timestamp,\n// last_claim_timestamp, true_price_paid\n\nimport { BillsConfig, ChainId } from '@ape.swap/apeswap-lists'\nimport type { UserOwnedBillsData, UserBill } from '../../types/yourbonds'\nimport type { BondsData } from '../../types/bonds'\nimport type { TokenPrices } from '../tokenPrices/useTokenPrices'\nimport { SUI_PACKAGE_ID, SUI_PLACEHOLDER_BILL_IMAGE } from '../../constants/suiConstants'\nimport { getSuiClient } from '../../utils/suiHelpers'\nimport axios from 'axios'\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\ninterface SuiBondNftFields {\n bill_id: string\n bond_market: string\n uri: string\n}\n\ninterface SuiBillFields {\n payout: string\n payout_claimed: string\n vesting_term: string\n vesting_start_timestamp: string\n last_claim_timestamp: string\n true_price_paid: string\n}\n\n/**\n * Fetch all BondNFT objects owned by a user address.\n * Returns the parsed content fields for each NFT.\n */\nasync function fetchUserBondNfts(userAddress: string): Promise<{ objectId: string; fields: SuiBondNftFields }[]> {\n const client = getSuiClient()\n const structType = `${SUI_PACKAGE_ID}::bond_nft::BondNFT`\n\n const results: { objectId: string; fields: SuiBondNftFields }[] = []\n let cursor: string | null | undefined = undefined\n let hasNextPage = true\n\n while (hasNextPage) {\n const response = await client.getOwnedObjects({\n owner: userAddress,\n filter: { StructType: structType },\n options: { showContent: true },\n cursor: cursor ?? undefined,\n })\n\n for (const item of response.data) {\n if (!item.data?.content || item.data.content.dataType !== 'moveObject') continue\n const fields = item.data.content.fields as unknown as SuiBondNftFields\n results.push({ objectId: item.data.objectId, fields })\n }\n\n hasNextPage = response.hasNextPage\n cursor = response.nextCursor\n }\n\n return results\n}\n\n/**\n * Read a single Bill from a BondMarket's `bills` Table by bill_id.\n *\n * The BondMarket is a shared object whose `bills` field is a `Table<u64, Bill>`.\n * Sui stores Table entries as dynamic fields on the Table's UID. We first read\n * the BondMarket object to get the Table's object ID, then query the dynamic\n * field for the specific bill_id.\n */\nasync function readBillFromMarket(\n marketObjectId: string,\n billId: string,\n): Promise<SuiBillFields & { cliffPeriod: number }> {\n const client = getSuiClient()\n\n // Step 1: Read the BondMarket object to find the `bills` Table object ID.\n // The `bills` field in a Move struct with `Table<u64, Bill>` is stored as an\n // object ID in the parent object's fields.\n const marketObj = await client.getObject({\n id: marketObjectId,\n options: { showContent: true },\n })\n\n if (!marketObj.data?.content || marketObj.data.content.dataType !== 'moveObject') {\n throw new Error(`[Sui] BondMarket ${marketObjectId} not found or not a Move object`)\n }\n\n const marketFields = marketObj.data.content.fields as Record<string, any>\n // Table fields in Sui are serialised as { id: { id: \"0x...\" }, size: N }\n const billsTableId = marketFields?.bills?.fields?.id?.id ?? marketFields?.bills?.id?.id\n if (!billsTableId) {\n throw new Error(`[Sui] Could not extract bills table ID from BondMarket ${marketObjectId}`)\n }\n\n // Step 2: Read the dynamic field for this bill_id from the Table.\n const billObj = await client.getDynamicFieldObject({\n parentId: billsTableId,\n name: { type: 'u64', value: billId },\n })\n\n if (!billObj.data?.content || billObj.data.content.dataType !== 'moveObject') {\n throw new Error(`[Sui] Bill ${billId} not found in market ${marketObjectId}`)\n }\n\n // The dynamic field value is nested under `fields.value` (or `fields.value.fields`\n // depending on serialisation depth).\n const dfFields = billObj.data.content.fields as Record<string, any>\n const billValue = dfFields?.value?.fields ?? dfFields?.value ?? dfFields\n\n // Extract cliff period from the market's vesting_config\n const vestingConfig = marketFields?.vesting_config\n const cliffPeriod = vestingConfig?.variant === 'CliffLinear' ? Number(vestingConfig?.fields?.cliff_period ?? 0) : 0\n\n return { ...(billValue as SuiBillFields), cliffPeriod }\n}\n\n// ---------------------------------------------------------------------------\n// Main export\n// ---------------------------------------------------------------------------\n\nexport async function fetchUserOwnedSuiBonds(\n user: string | undefined,\n bondData: BillsConfig[],\n tokenPrices: Partial<Record<ChainId, TokenPrices[]>>,\n priceApiUrl?: string,\n): Promise<UserOwnedBillsData[]> {\n if (!user) return []\n\n // Build one `UserOwnedBillsData` per known bond config. We always return\n // the outer shell so downstream code (`getUserBonds` in useUserBonds.ts)\n // can match bills back to their bond config.\n const suiKey = ChainId.SUI_MAINNET\n const suiPrices = tokenPrices?.[suiKey] ?? []\n\n // Index bonds by lowercased market address for O(1) lookup when matching\n // NFTs back to their market.\n const bondsByMarket = new Map<string, BillsConfig>()\n for (const bond of bondData) {\n const marketAddr = bond.contractAddress[suiKey]\n if (marketAddr) bondsByMarket.set(marketAddr.toLowerCase(), bond)\n }\n\n // Seed the result with empty shells so every bond is represented.\n const result: UserOwnedBillsData[] = bondData.map((bond) => ({\n index: bond.index,\n userOwnedBills: [] as UserBill[],\n }))\n const indexByBondIndex = new Map<number, UserOwnedBillsData>()\n for (const entry of result) indexByBondIndex.set(entry.index, entry)\n\n try {\n const nfts = await fetchUserBondNfts(user)\n if (nfts.length === 0) return result\n\n // For each BondNFT the user owns, resolve its market, read the bill data,\n // and compute vesting progress. NFTs whose market is not in our bondData\n // are silently skipped (they belong to a market the SDK isn't configured\n // to display).\n await Promise.all(\n nfts.map(async (nft) => {\n try {\n const { fields } = nft\n const billId = String(fields.bill_id)\n const marketAddr = fields.bond_market\n\n const bond = bondsByMarket.get(marketAddr.toLowerCase())\n if (!bond) return\n\n const billInfo = await readBillFromMarket(marketAddr, billId)\n\n const principalAddr = bond.lpToken.address[suiKey]?.toLowerCase()\n const payoutAddr = bond.earnToken.address[suiKey]?.toLowerCase()\n let principalPrice = suiPrices.find((t) => t.tokenAddress.toLowerCase() === principalAddr)?.price\n let payoutPrice = suiPrices.find((t) => t.tokenAddress.toLowerCase() === payoutAddr)?.price\n\n // Fallback: individual price-api call (same pattern as fetchBillsUserAptos.ts).\n // TODO(sui): price-api pending Sui support. Fallback to hardcoded prices.\n if (principalPrice === undefined && priceApiUrl) {\n try {\n const res = await axios.get(\n `${priceApiUrl}/realtime/price?token=${bond.lpToken.address[suiKey]}&chain=${suiKey}`,\n )\n principalPrice = parseFloat(res.data.price ?? '0')\n } catch {\n principalPrice = 1.0\n }\n }\n if (payoutPrice === undefined && priceApiUrl) {\n try {\n const res = await axios.get(\n `${priceApiUrl}/realtime/price?token=${bond.earnToken.address[suiKey]}&chain=${suiKey}`,\n )\n payoutPrice = parseFloat(res.data.price ?? '0')\n } catch {\n payoutPrice = 0.05\n }\n }\n\n const payoutTotal = String(billInfo.payout ?? '0')\n const payoutClaimed = String(billInfo.payout_claimed ?? '0')\n const payoutRemaining = (BigInt(payoutTotal) - BigInt(payoutClaimed)).toString()\n const vestingStart = String(billInfo.vesting_start_timestamp ?? '0')\n const lastClaim = String(billInfo.last_claim_timestamp ?? vestingStart)\n\n // Compute vesting progress client-side using the same curve as the contract.\n // Supports both Linear and CliffLinear vesting configurations.\n const nowSeconds = Math.floor(Date.now() / 1000)\n const vestingTerm = parseInt(String(billInfo.vesting_term ?? '0'))\n const vestingStartNum = parseInt(vestingStart)\n const cliffPeriod = billInfo.cliffPeriod ?? 0\n const elapsed = Math.max(0, nowSeconds - vestingStartNum)\n\n let totalVested: number\n if (cliffPeriod > 0) {\n // CliffLinear: nothing vests until cliff passes, then linear over remaining term\n if (elapsed < cliffPeriod) {\n totalVested = 0\n } else if (elapsed >= vestingTerm) {\n totalVested = parseInt(payoutTotal)\n } else {\n const elapsedAfterCliff = elapsed - cliffPeriod\n const vestingAfterCliff = vestingTerm - cliffPeriod\n totalVested =\n vestingAfterCliff > 0\n ? Math.floor((parseInt(payoutTotal) * elapsedAfterCliff) / vestingAfterCliff)\n : parseInt(payoutTotal)\n }\n } else {\n // Linear: standard proportional vesting\n const vestedFraction = vestingTerm > 0 ? Math.min(1, elapsed / vestingTerm) : 1\n totalVested = Math.floor(parseFloat(payoutTotal) * vestedFraction)\n }\n\n const claimable = Math.max(0, totalVested - parseInt(payoutClaimed))\n\n // Compute human-readable amounts for the modal display.\n const payoutDecimals = bond.earnToken.decimals[suiKey] ?? 9\n const principalDecimals = bond.lpToken.decimals[suiKey] ?? 9\n const payoutHuman = parseFloat(payoutTotal) / 10 ** payoutDecimals\n // Reconstruct deposit from payout and true_price_paid:\n // price = principal_amount * 1e8 / payout_amount -> principal = payout * price / 1e8\n const truePricePaid = parseFloat(String(billInfo.true_price_paid ?? '0'))\n const depositAtomic = (parseFloat(payoutTotal) * truePricePaid) / 1e8\n const depositHuman = depositAtomic / 10 ** principalDecimals\n const depositUSD = depositHuman * (principalPrice ?? 0)\n\n const userBill: UserBill = {\n // `UserBill.address` is used by the SDK's claim flow. On Sui, this\n // is the BondNFT object ID that the user passes to `bond::claim`.\n address: nft.objectId,\n id: billId,\n vestingTerm: String(billInfo.vesting_term ?? '0'),\n payout: payoutRemaining,\n totalPayout: payoutTotal,\n truePricePaid: String(billInfo.true_price_paid ?? '0'),\n lastBlockTimestamp: String(lastClaim),\n vestingStartTimestamp: String(vestingStart),\n pendingRewards: String(claimable),\n billNftAddress: bond.billNnftAddress[suiKey] ?? '',\n payoutClaimed,\n nftData: {\n tokenId: 0,\n billNftId: parseInt(billId),\n processing: false,\n image: SUI_PLACEHOLDER_BILL_IMAGE,\n // Populate `data` so YourBondsModal can display Deposit/Bond Value.\n // api-v2 won't enrich Sui bills, so we compute from on-chain data.\n data: {\n dollarValue: depositUSD,\n payout: payoutHuman,\n billContract: marketAddr,\n billNftAddress: bond.billNnftAddress[suiKey] ?? '',\n billNftId: parseInt(billId),\n blockNumber: 0,\n bondArtCollection: '',\n bondPartner: '',\n bondVersion: bond.version ?? '',\n chainId: suiKey,\n createTransactionHash: '',\n createdAddressOwner: user,\n createdAt: parseInt(String(vestingStart)),\n deposit: depositHuman,\n expires: parseInt(String(vestingStart)) + parseInt(String(billInfo.vesting_term ?? '0')),\n pairName: `${bond.lpToken.symbol}-${bond.earnToken.symbol}`,\n payoutToken: bond.earnToken.address[suiKey] ?? '',\n payoutTokenData: {\n address: bond.earnToken.address[suiKey] ?? '',\n name: bond.earnToken.symbol,\n symbol: bond.earnToken.symbol,\n decimals: bond.earnToken.decimals,\n },\n payoutTokenPrice: (payoutPrice ?? 0).toString(),\n principalToken: bond.lpToken.address[suiKey] ?? '',\n token0: {\n address: bond.lpToken.address[suiKey] ?? '',\n symbol: bond.lpToken.symbol,\n name: bond.lpToken.symbol,\n decimals: bond.lpToken.decimals,\n },\n token1: {\n address: bond.earnToken.address[suiKey] ?? '',\n symbol: bond.earnToken.symbol,\n name: bond.earnToken.symbol,\n decimals: bond.earnToken.decimals,\n },\n type: bond.billType ?? 'reserve',\n vestingPeriodSeconds: parseInt(String(billInfo.vesting_term ?? '0')),\n },\n },\n bond: {\n ...bond,\n payoutTokenPrice: payoutPrice?.toString(),\n principalTokenPrice: principalPrice?.toString(),\n } as BondsData,\n }\n\n const entry = indexByBondIndex.get(bond.index)\n entry?.userOwnedBills.push(userBill)\n } catch (billErr) {\n console.warn(`[Sui] Failed to read bill from NFT ${nft.objectId}`, billErr)\n }\n }),\n )\n } catch (e) {\n console.warn(`[Sui] Failed to list user bills for ${user}`, e)\n }\n\n return result\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BillsConfig } from '@ape.swap/apeswap-lists';
|
|
2
|
+
import { BondsData } from '../../types/bonds';
|
|
3
|
+
import { TokenPrices } from '../tokenPrices/useTokenPrices';
|
|
4
|
+
/**
|
|
5
|
+
* Enrich Aptos bond configs into full BondsData objects.
|
|
6
|
+
*
|
|
7
|
+
* Calls `bond::market_info(market)` for each config and projects the tuple
|
|
8
|
+
* onto BondsData. Scale conversion: contract returns `true_bill_price` as u64
|
|
9
|
+
* scaled by PRICE_DECIMALS = 1e8; the SDK stores `trueBondPrice` scaled by
|
|
10
|
+
* 1e18 (legacy EVM format) → multiply by 1e10.
|
|
11
|
+
*/
|
|
12
|
+
export declare const enrichAptosBonds: (aptosConfigs?: BillsConfig[], aptosPrices?: TokenPrices[], priceApiUrl?: string) => Promise<BondsData[]>;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import BigNumber from 'bignumber.js';
|
|
2
|
+
import { ChainId } from '@ape.swap/apeswap-lists';
|
|
3
|
+
import { readAptosMarketInfo } from '../../utils/aptosHelpers.js';
|
|
4
|
+
import axios from 'axios';
|
|
5
|
+
|
|
6
|
+
// =============================================================================
|
|
7
|
+
// Aptos bond enrichment — builds BondsData[] from BillsConfig[] + prices
|
|
8
|
+
// =============================================================================
|
|
9
|
+
//
|
|
10
|
+
// On-chain first: reads bond::market_info via view function for each config
|
|
11
|
+
// and projects the tuple onto BondsData. No backend dependency (realtime-api
|
|
12
|
+
// does not support Aptos).
|
|
13
|
+
const APTOS_KEY = ChainId.APTOS_MAINNET;
|
|
14
|
+
/**
|
|
15
|
+
* Enrich Aptos bond configs into full BondsData objects.
|
|
16
|
+
*
|
|
17
|
+
* Calls `bond::market_info(market)` for each config and projects the tuple
|
|
18
|
+
* onto BondsData. Scale conversion: contract returns `true_bill_price` as u64
|
|
19
|
+
* scaled by PRICE_DECIMALS = 1e8; the SDK stores `trueBondPrice` scaled by
|
|
20
|
+
* 1e18 (legacy EVM format) → multiply by 1e10.
|
|
21
|
+
*/
|
|
22
|
+
const enrichAptosBonds = async (aptosConfigs, aptosPrices, priceApiUrl) => {
|
|
23
|
+
if (!aptosConfigs || aptosConfigs?.length === 0)
|
|
24
|
+
return [];
|
|
25
|
+
const enriched = await Promise.all(aptosConfigs.map(async (bond) => {
|
|
26
|
+
const marketAddr = bond.contractAddress[APTOS_KEY];
|
|
27
|
+
if (!marketAddr)
|
|
28
|
+
return null;
|
|
29
|
+
try {
|
|
30
|
+
// Firstly we fetch prices
|
|
31
|
+
let principalPrice = aptosPrices?.find((t) => t.tokenAddress.toLowerCase() === principalAddr)?.price;
|
|
32
|
+
if (principalPrice === undefined) {
|
|
33
|
+
try {
|
|
34
|
+
const res = await axios.get(`${priceApiUrl}/realtime/price?token=${bond?.lpToken?.address?.[bond?.chainId]}&chain=${bond?.chainId}`);
|
|
35
|
+
console.log('Individual call for: ', bond.lpToken.symbol, '. Price: ', res.data.price);
|
|
36
|
+
principalPrice = res.data.price ?? 0;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
console.error('Failed to fetch price for: ', bond.lpToken.symbol);
|
|
40
|
+
principalPrice = 0;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
let payoutPrice = aptosPrices?.find((t) => t.tokenAddress.toLowerCase() === payoutAddr)?.price;
|
|
44
|
+
if (payoutPrice === undefined) {
|
|
45
|
+
try {
|
|
46
|
+
// Missing token price, therefor make a single call to api to fetch it
|
|
47
|
+
const res = await axios.get(`${priceApiUrl}/realtime/price?token=${bond?.earnToken?.address?.[bond?.chainId]}&chain=${bond?.chainId}`);
|
|
48
|
+
console.log('Individual call for: ', bond.earnToken.symbol, '. Price: ', res.data.price);
|
|
49
|
+
payoutPrice = res.data.price ?? 0;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
console.error('Failed to fetch price for: ', bond.earnToken.symbol);
|
|
53
|
+
payoutPrice = 0;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const info = await readAptosMarketInfo(marketAddr);
|
|
57
|
+
const principalAddr = bond.lpToken.address[APTOS_KEY]?.toLowerCase();
|
|
58
|
+
const payoutAddr = bond.earnToken.address[APTOS_KEY]?.toLowerCase();
|
|
59
|
+
// Convert on-chain u64 (scaled 1e8) to the SDK's legacy 1e18 scale
|
|
60
|
+
const trueBillPriceU64 = info[17];
|
|
61
|
+
const trueBondPriceScaled = (BigInt(trueBillPriceU64) * 10n ** 10n).toString();
|
|
62
|
+
const trueBondPriceHuman = Number(trueBillPriceU64) / 1e8;
|
|
63
|
+
// Same formula as getRawDiscount / getRawBonus in state/bonds/utils.ts
|
|
64
|
+
const discount = payoutPrice > 0 ? ((payoutPrice - principalPrice * trueBondPriceHuman) / payoutPrice) * 100 : 0;
|
|
65
|
+
const bonus = discount > 0 && discount < 100 ? (discount / (100 - discount)) * 100 : 0;
|
|
66
|
+
// Fees: u64 in PERCENTAGE_BASE (1e6) → divide by 10_000 for human %
|
|
67
|
+
const feeInPayout = Number(info[14]) / 10000;
|
|
68
|
+
const feeInPrincipal = Number(info[13]) / 10000;
|
|
69
|
+
const trueBondPriceWithFee = feeInPayout < 100 ? trueBondPriceHuman * (1 / ((100 - feeInPayout) / 100)) : trueBondPriceHuman;
|
|
70
|
+
const discountWithFee = payoutPrice > 0 ? ((payoutPrice - principalPrice * trueBondPriceWithFee) / payoutPrice) * 100 : 0;
|
|
71
|
+
const bonusWithFee = discountWithFee > 0 && discountWithFee < 100 ? (discountWithFee / (100 - discountWithFee)) * 100 : 0;
|
|
72
|
+
const payoutDecimals = bond.earnToken.decimals[APTOS_KEY] ?? 8;
|
|
73
|
+
const tokensRemaining = new BigNumber(info[23])
|
|
74
|
+
.minus(new BigNumber(info[5]))
|
|
75
|
+
.div(new BigNumber(10).pow(payoutDecimals))
|
|
76
|
+
.toString();
|
|
77
|
+
return {
|
|
78
|
+
...bond,
|
|
79
|
+
soldOut: info[2] || info[3] ? true : bond.soldOut,
|
|
80
|
+
maxTotalPayout: String(info[23]),
|
|
81
|
+
totalPayoutGiven: String(info[5]),
|
|
82
|
+
maxPayout: String(info[21]),
|
|
83
|
+
tokensRemaining,
|
|
84
|
+
showcaseTokenName: bond.earnToken.symbol,
|
|
85
|
+
vestingTerm: Number(info[19]),
|
|
86
|
+
feeInPayout,
|
|
87
|
+
feeInPrincipal,
|
|
88
|
+
trueBondPrices: [
|
|
89
|
+
{
|
|
90
|
+
trueBondPrice: trueBondPriceScaled,
|
|
91
|
+
points: '0',
|
|
92
|
+
discount,
|
|
93
|
+
discountWithFee,
|
|
94
|
+
bonus,
|
|
95
|
+
bonusWithFee,
|
|
96
|
+
boost: 0,
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
principalTokenPrice: principalPrice.toString(),
|
|
100
|
+
payoutTokenPrice: payoutPrice.toString(),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
console.warn(`[Aptos] Failed to read market_info for ${marketAddr}`, e);
|
|
105
|
+
// Hide the bond from the list when on-chain data is unavailable —
|
|
106
|
+
// showing a card with all zeros is confusing for users.
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
}));
|
|
110
|
+
return enriched.filter((b) => b !== null);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export { enrichAptosBonds };
|
|
114
|
+
//# sourceMappingURL=fetchBondsDataAptos.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetchBondsDataAptos.js","sources":["../../../src/state/bonds/fetchBondsDataAptos.ts"],"sourcesContent":["// =============================================================================\n// Aptos bond enrichment — builds BondsData[] from BillsConfig[] + prices\n// =============================================================================\n//\n// On-chain first: reads bond::market_info via view function for each config\n// and projects the tuple onto BondsData. No backend dependency (realtime-api\n// does not support Aptos).\n\nimport BigNumber from 'bignumber.js'\nimport { BillsConfig, ChainId } from '@ape.swap/apeswap-lists'\nimport { BondsData } from '../../types/bonds'\nimport { TokenPrices } from '../tokenPrices/useTokenPrices'\nimport { readAptosMarketInfo } from '../../utils/aptosHelpers'\nimport axios from 'axios'\n\nconst APTOS_KEY = ChainId.APTOS_MAINNET\n\n/**\n * Enrich Aptos bond configs into full BondsData objects.\n *\n * Calls `bond::market_info(market)` for each config and projects the tuple\n * onto BondsData. Scale conversion: contract returns `true_bill_price` as u64\n * scaled by PRICE_DECIMALS = 1e8; the SDK stores `trueBondPrice` scaled by\n * 1e18 (legacy EVM format) → multiply by 1e10.\n */\nexport const enrichAptosBonds = async (\n aptosConfigs?: BillsConfig[],\n aptosPrices?: TokenPrices[],\n priceApiUrl?: string,\n): Promise<BondsData[]> => {\n if (!aptosConfigs || aptosConfigs?.length === 0) return []\n\n const enriched = await Promise.all(\n aptosConfigs.map(async (bond): Promise<BondsData | null> => {\n const marketAddr = bond.contractAddress[APTOS_KEY]\n if (!marketAddr) return null\n try {\n // Firstly we fetch prices\n let principalPrice = aptosPrices?.find((t) => t.tokenAddress.toLowerCase() === principalAddr)?.price!\n if (principalPrice === undefined) {\n try {\n const res = await axios.get(\n `${priceApiUrl}/realtime/price?token=${bond?.lpToken?.address?.[bond?.chainId]}&chain=${bond?.chainId}`,\n )\n console.log('Individual call for: ', bond.lpToken.symbol, '. Price: ', res.data.price)\n principalPrice = res.data.price ?? 0\n } catch {\n console.error('Failed to fetch price for: ', bond.lpToken.symbol)\n principalPrice = 0\n }\n }\n\n let payoutPrice = aptosPrices?.find((t) => t.tokenAddress.toLowerCase() === payoutAddr)?.price!\n if (payoutPrice === undefined) {\n try {\n // Missing token price, therefor make a single call to api to fetch it\n const res = await axios.get(\n `${priceApiUrl}/realtime/price?token=${bond?.earnToken?.address?.[bond?.chainId]}&chain=${bond?.chainId}`,\n )\n console.log('Individual call for: ', bond.earnToken.symbol, '. Price: ', res.data.price)\n payoutPrice = res.data.price ?? 0\n } catch {\n console.error('Failed to fetch price for: ', bond.earnToken.symbol)\n payoutPrice = 0\n }\n }\n\n const info = await readAptosMarketInfo(marketAddr)\n const principalAddr = bond.lpToken.address[APTOS_KEY]?.toLowerCase()\n const payoutAddr = bond.earnToken.address[APTOS_KEY]?.toLowerCase()\n\n // Convert on-chain u64 (scaled 1e8) to the SDK's legacy 1e18 scale\n const trueBillPriceU64 = info[17]\n const trueBondPriceScaled = (BigInt(trueBillPriceU64) * 10n ** 10n).toString()\n const trueBondPriceHuman = Number(trueBillPriceU64) / 1e8\n\n // Same formula as getRawDiscount / getRawBonus in state/bonds/utils.ts\n const discount = payoutPrice > 0 ? ((payoutPrice - principalPrice * trueBondPriceHuman) / payoutPrice) * 100 : 0\n const bonus = discount > 0 && discount < 100 ? (discount / (100 - discount)) * 100 : 0\n\n // Fees: u64 in PERCENTAGE_BASE (1e6) → divide by 10_000 for human %\n const feeInPayout = Number(info[14]) / 10_000\n const feeInPrincipal = Number(info[13]) / 10_000\n const trueBondPriceWithFee =\n feeInPayout < 100 ? trueBondPriceHuman * (1 / ((100 - feeInPayout) / 100)) : trueBondPriceHuman\n const discountWithFee =\n payoutPrice > 0 ? ((payoutPrice - principalPrice * trueBondPriceWithFee) / payoutPrice) * 100 : 0\n const bonusWithFee =\n discountWithFee > 0 && discountWithFee < 100 ? (discountWithFee / (100 - discountWithFee)) * 100 : 0\n\n const payoutDecimals = bond.earnToken.decimals[APTOS_KEY] ?? 8\n const tokensRemaining = new BigNumber(info[23])\n .minus(new BigNumber(info[5]))\n .div(new BigNumber(10).pow(payoutDecimals))\n .toString()\n\n return {\n ...bond,\n soldOut: info[2] || info[3] ? true : bond.soldOut,\n maxTotalPayout: String(info[23]),\n totalPayoutGiven: String(info[5]),\n maxPayout: String(info[21]),\n tokensRemaining,\n showcaseTokenName: bond.earnToken.symbol,\n vestingTerm: Number(info[19]),\n feeInPayout,\n feeInPrincipal,\n trueBondPrices: [\n {\n trueBondPrice: trueBondPriceScaled,\n points: '0',\n discount,\n discountWithFee,\n bonus,\n bonusWithFee,\n boost: 0,\n },\n ],\n principalTokenPrice: principalPrice.toString(),\n payoutTokenPrice: payoutPrice.toString(),\n }\n } catch (e) {\n console.warn(`[Aptos] Failed to read market_info for ${marketAddr}`, e)\n // Hide the bond from the list when on-chain data is unavailable —\n // showing a card with all zeros is confusing for users.\n return null\n }\n }),\n )\n return enriched.filter((b): b is BondsData => b !== null)\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BillsConfig } from '@ape.swap/apeswap-lists';
|
|
2
|
+
import { BondsData } from '../../types/bonds';
|
|
3
|
+
import { TokenPrices } from '../tokenPrices/useTokenPrices';
|
|
4
|
+
/**
|
|
5
|
+
* Enrich Sui bond configs into full BondsData objects.
|
|
6
|
+
*
|
|
7
|
+
* Reads each BondMarket object directly via `getObject` and computes
|
|
8
|
+
* true_bill_price client-side using the same bond_math formulas as the
|
|
9
|
+
* Move contract. Scale conversion: computed `true_bill_price` is u64
|
|
10
|
+
* scaled by PRICE_DECIMALS = 1e8; the SDK stores `trueBondPrice` scaled
|
|
11
|
+
* by 1e18 (legacy EVM format) → multiply by 1e10.
|
|
12
|
+
*/
|
|
13
|
+
export declare const enrichSuiBonds: (bonds?: BillsConfig[], prices?: TokenPrices[], priceApiUrl?: string) => Promise<BondsData[]>;
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import BigNumber from 'bignumber.js';
|
|
2
|
+
import { ChainId } from '@ape.swap/apeswap-lists';
|
|
3
|
+
import { getSuiClient } from '../../utils/suiHelpers.js';
|
|
4
|
+
import axios from 'axios';
|
|
5
|
+
|
|
6
|
+
// =============================================================================
|
|
7
|
+
// Sui bond enrichment — builds BondsData[] from BillsConfig[] + prices
|
|
8
|
+
// =============================================================================
|
|
9
|
+
//
|
|
10
|
+
// On-chain first: reads BondMarket objects directly via getObject for each
|
|
11
|
+
// config and projects the fields onto BondsData. No backend dependency
|
|
12
|
+
// (realtime-api does not support Sui).
|
|
13
|
+
const SUI_KEY = ChainId.SUI_MAINNET;
|
|
14
|
+
// Contract constants — must match the Move source
|
|
15
|
+
const PRICE_DECIMALS = 100000000n; // 1e8
|
|
16
|
+
const PERCENTAGE_BASE = 1000000n; // 1e6
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Helpers — replicate bond_math on the client so we can compute true_price
|
|
19
|
+
// from the raw object fields without needing a view function call.
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
const pow10 = (n) => 10n ** BigInt(n);
|
|
22
|
+
/** debt_ratio = (current_debt * payout_scale) / payout_initial_supply */
|
|
23
|
+
const calculateDebtRatio = (currentDebt, payoutInitialSupply, payoutScale) => {
|
|
24
|
+
if (payoutInitialSupply === 0n)
|
|
25
|
+
return 0n;
|
|
26
|
+
return (currentDebt * payoutScale) / payoutInitialSupply;
|
|
27
|
+
};
|
|
28
|
+
/** value_of_token — convert amount from one decimal basis to another */
|
|
29
|
+
const valueOfToken = (fromDecimals, toDecimals, amount) => {
|
|
30
|
+
if (toDecimals >= fromDecimals) {
|
|
31
|
+
return amount * pow10(toDecimals - fromDecimals);
|
|
32
|
+
}
|
|
33
|
+
return amount / pow10(fromDecimals - toDecimals);
|
|
34
|
+
};
|
|
35
|
+
/** bond_price = (control_variable * debt_ratio * token_scale) / PRICE_DECIMALS */
|
|
36
|
+
const calculateBondPrice = (controlVariable, debtRatio, tokenScale) => {
|
|
37
|
+
const temp = controlVariable * debtRatio;
|
|
38
|
+
return (temp * tokenScale) / PRICE_DECIMALS;
|
|
39
|
+
};
|
|
40
|
+
/** true_price = (base_price * PERCENTAGE_BASE) / (PERCENTAGE_BASE - fee_in_principal) */
|
|
41
|
+
const calculateTruePrice = (basePrice, feeInPrincipal, minimumPrice) => {
|
|
42
|
+
const denominator = PERCENTAGE_BASE - feeInPrincipal;
|
|
43
|
+
if (denominator === 0n)
|
|
44
|
+
return basePrice;
|
|
45
|
+
const truePrice = (basePrice * PERCENTAGE_BASE) / denominator;
|
|
46
|
+
return truePrice < minimumPrice ? minimumPrice : truePrice;
|
|
47
|
+
};
|
|
48
|
+
const extractMarketFields = (content) => {
|
|
49
|
+
if (!content?.fields)
|
|
50
|
+
return null;
|
|
51
|
+
const f = content.fields;
|
|
52
|
+
const terms = f.terms?.fields ?? f.terms;
|
|
53
|
+
if (!terms)
|
|
54
|
+
return null;
|
|
55
|
+
return {
|
|
56
|
+
paused: Boolean(f.paused),
|
|
57
|
+
emergency_paused: Boolean(f.emergency_paused),
|
|
58
|
+
total_principal_billed: String(f.total_principal_billed ?? '0'),
|
|
59
|
+
total_payout_given: String(f.total_payout_given ?? '0'),
|
|
60
|
+
total_debt: String(f.total_debt ?? '0'),
|
|
61
|
+
payout_token_initial_supply: String(f.payout_token_initial_supply ?? '0'),
|
|
62
|
+
payout_decimals: Number(f.payout_decimals ?? 9),
|
|
63
|
+
principal_decimals: Number(f.principal_decimals ?? 9),
|
|
64
|
+
fee_in_principal: String(f.fee_in_principal ?? '0'),
|
|
65
|
+
fee_in_payout: String(f.fee_in_payout ?? '0'),
|
|
66
|
+
cliff_period: f.vesting_config?.variant === 'CliffLinear' ? Number(f.vesting_config?.fields?.cliff_period ?? 0) : 0,
|
|
67
|
+
terms: {
|
|
68
|
+
fields: {
|
|
69
|
+
control_variable: String(terms.control_variable ?? '0'),
|
|
70
|
+
vesting_term: String(terms.vesting_term ?? '0'),
|
|
71
|
+
minimum_price: String(terms.minimum_price ?? '0'),
|
|
72
|
+
max_payout: String(terms.max_payout ?? '0'),
|
|
73
|
+
max_debt: String(terms.max_debt ?? '0'),
|
|
74
|
+
max_total_payout: String(terms.max_total_payout ?? '0'),
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
// Main enrichment function
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
/**
|
|
83
|
+
* Enrich Sui bond configs into full BondsData objects.
|
|
84
|
+
*
|
|
85
|
+
* Reads each BondMarket object directly via `getObject` and computes
|
|
86
|
+
* true_bill_price client-side using the same bond_math formulas as the
|
|
87
|
+
* Move contract. Scale conversion: computed `true_bill_price` is u64
|
|
88
|
+
* scaled by PRICE_DECIMALS = 1e8; the SDK stores `trueBondPrice` scaled
|
|
89
|
+
* by 1e18 (legacy EVM format) → multiply by 1e10.
|
|
90
|
+
*/
|
|
91
|
+
const enrichSuiBonds = async (bonds, prices, priceApiUrl) => {
|
|
92
|
+
if (!bonds || bonds?.length === 0)
|
|
93
|
+
return [];
|
|
94
|
+
const client = getSuiClient();
|
|
95
|
+
const enriched = await Promise.all(bonds.map(async (bond) => {
|
|
96
|
+
const marketAddr = bond.contractAddress[SUI_KEY];
|
|
97
|
+
if (!marketAddr)
|
|
98
|
+
return null;
|
|
99
|
+
try {
|
|
100
|
+
const obj = await client.getObject({
|
|
101
|
+
id: marketAddr,
|
|
102
|
+
options: { showContent: true },
|
|
103
|
+
});
|
|
104
|
+
const fields = extractMarketFields(obj.data?.content);
|
|
105
|
+
if (!fields) {
|
|
106
|
+
console.warn(`[Sui] No content fields for market ${marketAddr}`);
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
let principalPrice = prices?.find((t) => t.tokenAddress.toLowerCase() === principalAddr)?.price;
|
|
110
|
+
if (principalPrice === undefined) {
|
|
111
|
+
try {
|
|
112
|
+
const res = await axios.get(`${priceApiUrl}/realtime/price?token=${bond?.lpToken?.address?.[bond?.chainId]}&chain=${bond?.chainId}`);
|
|
113
|
+
console.log('Individual call for: ', bond.lpToken.symbol, '. Price: ', res.data.price);
|
|
114
|
+
principalPrice = res.data.price ?? 0;
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
console.error('Failed to fetch price for: ', bond.lpToken.symbol);
|
|
118
|
+
principalPrice = 0;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
let payoutPrice = prices?.find((t) => t.tokenAddress.toLowerCase() === payoutAddr)?.price;
|
|
122
|
+
if (payoutPrice === undefined) {
|
|
123
|
+
try {
|
|
124
|
+
// Missing token price, therefor make a single call to api to fetch it
|
|
125
|
+
const res = await axios.get(`${priceApiUrl}/realtime/price?token=${bond?.earnToken?.address?.[bond?.chainId]}&chain=${bond?.chainId}`);
|
|
126
|
+
console.log('Individual call for: ', bond.earnToken.symbol, '. Price: ', res.data.price);
|
|
127
|
+
payoutPrice = res.data.price ?? 0;
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
console.error('Failed to fetch price for: ', bond.earnToken.symbol);
|
|
131
|
+
payoutPrice = 0;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const principalAddr = bond.lpToken.address[SUI_KEY]?.toLowerCase();
|
|
135
|
+
const payoutAddr = bond.earnToken.address[SUI_KEY]?.toLowerCase();
|
|
136
|
+
// ---------- Compute true_bill_price client-side ----------
|
|
137
|
+
const payoutDecimals = bond.earnToken.decimals[SUI_KEY] ?? fields.payout_decimals;
|
|
138
|
+
const principalDecimals = bond.lpToken.decimals?.[SUI_KEY] ?? fields.principal_decimals;
|
|
139
|
+
const totalDebt = BigInt(fields.total_debt);
|
|
140
|
+
const payoutInitialSupply = BigInt(fields.payout_token_initial_supply);
|
|
141
|
+
const controlVariable = BigInt(fields.terms.fields.control_variable);
|
|
142
|
+
const minimumPrice = BigInt(fields.terms.fields.minimum_price);
|
|
143
|
+
const feeInPrincipalRaw = BigInt(fields.fee_in_principal);
|
|
144
|
+
// Replicate calculate_current_debt → calculate_price → calculate_true_price
|
|
145
|
+
const currentDebtPayout = valueOfToken(principalDecimals, payoutDecimals, totalDebt);
|
|
146
|
+
const payoutScale = pow10(payoutDecimals);
|
|
147
|
+
const principalScale = pow10(principalDecimals);
|
|
148
|
+
const debtRatio = calculateDebtRatio(currentDebtPayout, payoutInitialSupply, payoutScale);
|
|
149
|
+
const basePrice = calculateBondPrice(controlVariable, debtRatio, principalScale);
|
|
150
|
+
const trueBillPriceU64 = calculateTruePrice(basePrice, feeInPrincipalRaw, minimumPrice);
|
|
151
|
+
// Convert on-chain u64 (scaled 1e8) to the SDK's legacy 1e18 scale
|
|
152
|
+
const trueBondPriceScaled = (trueBillPriceU64 * 10n ** 10n).toString();
|
|
153
|
+
const trueBondPriceHuman = Number(trueBillPriceU64) / 1e8;
|
|
154
|
+
// Same formula as getRawDiscount / getRawBonus in state/bonds/utils.ts
|
|
155
|
+
const discount = payoutPrice > 0 ? ((payoutPrice - principalPrice * trueBondPriceHuman) / payoutPrice) * 100 : 0;
|
|
156
|
+
const bonus = discount > 0 && discount < 100 ? (discount / (100 - discount)) * 100 : 0;
|
|
157
|
+
// Fees: u64 in PERCENTAGE_BASE (1e6) → divide by 10_000 for human %
|
|
158
|
+
const feeInPayout = Number(fields.fee_in_payout) / 10000;
|
|
159
|
+
const feeInPrincipal = Number(fields.fee_in_principal) / 10000;
|
|
160
|
+
const trueBondPriceWithFee = feeInPayout < 100 ? trueBondPriceHuman * (1 / ((100 - feeInPayout) / 100)) : trueBondPriceHuman;
|
|
161
|
+
const discountWithFee = payoutPrice > 0 ? ((payoutPrice - principalPrice * trueBondPriceWithFee) / payoutPrice) * 100 : 0;
|
|
162
|
+
const bonusWithFee = discountWithFee > 0 && discountWithFee < 100 ? (discountWithFee / (100 - discountWithFee)) * 100 : 0;
|
|
163
|
+
const tokensRemaining = new BigNumber(fields.terms.fields.max_total_payout)
|
|
164
|
+
.minus(new BigNumber(fields.total_payout_given))
|
|
165
|
+
.div(new BigNumber(10).pow(payoutDecimals))
|
|
166
|
+
.toString();
|
|
167
|
+
return {
|
|
168
|
+
...bond,
|
|
169
|
+
soldOut: fields.paused || fields.emergency_paused ? true : bond.soldOut,
|
|
170
|
+
maxTotalPayout: fields.terms.fields.max_total_payout,
|
|
171
|
+
totalPayoutGiven: fields.total_payout_given,
|
|
172
|
+
maxPayout: fields.terms.fields.max_payout,
|
|
173
|
+
tokensRemaining,
|
|
174
|
+
showcaseTokenName: bond.earnToken.symbol,
|
|
175
|
+
vestingTerm: Number(fields.terms.fields.vesting_term),
|
|
176
|
+
vestingCliff: fields.cliff_period || undefined,
|
|
177
|
+
feeInPayout,
|
|
178
|
+
feeInPrincipal,
|
|
179
|
+
trueBondPrices: [
|
|
180
|
+
{
|
|
181
|
+
trueBondPrice: trueBondPriceScaled,
|
|
182
|
+
points: '0',
|
|
183
|
+
discount,
|
|
184
|
+
discountWithFee,
|
|
185
|
+
bonus,
|
|
186
|
+
bonusWithFee,
|
|
187
|
+
boost: 0,
|
|
188
|
+
},
|
|
189
|
+
],
|
|
190
|
+
principalTokenPrice: principalPrice.toString(),
|
|
191
|
+
payoutTokenPrice: payoutPrice.toString(),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
catch (e) {
|
|
195
|
+
console.warn(`[Sui] Failed to read BondMarket for ${marketAddr}`, e);
|
|
196
|
+
// Hide the bond from the list when on-chain data is unavailable —
|
|
197
|
+
// showing a card with all zeros is confusing for users.
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
}));
|
|
201
|
+
return enriched.filter((b) => b !== null);
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
export { enrichSuiBonds };
|
|
205
|
+
//# sourceMappingURL=fetchBondsDataSui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetchBondsDataSui.js","sources":["../../../src/state/bonds/fetchBondsDataSui.ts"],"sourcesContent":["// =============================================================================\n// Sui bond enrichment — builds BondsData[] from BillsConfig[] + prices\n// =============================================================================\n//\n// On-chain first: reads BondMarket objects directly via getObject for each\n// config and projects the fields onto BondsData. No backend dependency\n// (realtime-api does not support Sui).\n\nimport BigNumber from 'bignumber.js'\nimport { BillsConfig, ChainId } from '@ape.swap/apeswap-lists'\nimport { BondsData } from '../../types/bonds'\nimport { TokenPrices } from '../tokenPrices/useTokenPrices'\nimport { getSuiClient } from '../../utils/suiHelpers'\nimport axios from 'axios'\n\nconst SUI_KEY = ChainId.SUI_MAINNET\n\n// Contract constants — must match the Move source\nconst PRICE_DECIMALS = 100_000_000n // 1e8\nconst PERCENTAGE_BASE = 1_000_000n // 1e6\n\n// ---------------------------------------------------------------------------\n// Helpers — replicate bond_math on the client so we can compute true_price\n// from the raw object fields without needing a view function call.\n// ---------------------------------------------------------------------------\n\nconst pow10 = (n: number): bigint => 10n ** BigInt(n)\n\n/** debt_ratio = (current_debt * payout_scale) / payout_initial_supply */\nconst calculateDebtRatio = (currentDebt: bigint, payoutInitialSupply: bigint, payoutScale: bigint): bigint => {\n if (payoutInitialSupply === 0n) return 0n\n return (currentDebt * payoutScale) / payoutInitialSupply\n}\n\n/** value_of_token — convert amount from one decimal basis to another */\nconst valueOfToken = (fromDecimals: number, toDecimals: number, amount: bigint): bigint => {\n if (toDecimals >= fromDecimals) {\n return amount * pow10(toDecimals - fromDecimals)\n }\n return amount / pow10(fromDecimals - toDecimals)\n}\n\n/** bond_price = (control_variable * debt_ratio * token_scale) / PRICE_DECIMALS */\nconst calculateBondPrice = (controlVariable: bigint, debtRatio: bigint, tokenScale: bigint): bigint => {\n const temp = controlVariable * debtRatio\n return (temp * tokenScale) / PRICE_DECIMALS\n}\n\n/** true_price = (base_price * PERCENTAGE_BASE) / (PERCENTAGE_BASE - fee_in_principal) */\nconst calculateTruePrice = (basePrice: bigint, feeInPrincipal: bigint, minimumPrice: bigint): bigint => {\n const denominator = PERCENTAGE_BASE - feeInPrincipal\n if (denominator === 0n) return basePrice\n const truePrice = (basePrice * PERCENTAGE_BASE) / denominator\n return truePrice < minimumPrice ? minimumPrice : truePrice\n}\n\n// ---------------------------------------------------------------------------\n// Object field extraction — Sui getObject returns nested content.fields\n// ---------------------------------------------------------------------------\n\ninterface SuiMarketFields {\n paused: boolean\n emergency_paused: boolean\n total_principal_billed: string\n total_payout_given: string\n total_debt: string\n payout_token_initial_supply: string\n payout_decimals: number\n principal_decimals: number\n fee_in_principal: string\n fee_in_payout: string\n cliff_period: number\n terms: {\n fields: {\n control_variable: string\n vesting_term: string\n minimum_price: string\n max_payout: string\n max_debt: string\n max_total_payout: string\n }\n }\n}\n\nconst extractMarketFields = (content: any): SuiMarketFields | null => {\n if (!content?.fields) return null\n const f = content.fields\n const terms = f.terms?.fields ?? f.terms\n if (!terms) return null\n return {\n paused: Boolean(f.paused),\n emergency_paused: Boolean(f.emergency_paused),\n total_principal_billed: String(f.total_principal_billed ?? '0'),\n total_payout_given: String(f.total_payout_given ?? '0'),\n total_debt: String(f.total_debt ?? '0'),\n payout_token_initial_supply: String(f.payout_token_initial_supply ?? '0'),\n payout_decimals: Number(f.payout_decimals ?? 9),\n principal_decimals: Number(f.principal_decimals ?? 9),\n fee_in_principal: String(f.fee_in_principal ?? '0'),\n fee_in_payout: String(f.fee_in_payout ?? '0'),\n cliff_period: f.vesting_config?.variant === 'CliffLinear' ? Number(f.vesting_config?.fields?.cliff_period ?? 0) : 0,\n terms: {\n fields: {\n control_variable: String(terms.control_variable ?? '0'),\n vesting_term: String(terms.vesting_term ?? '0'),\n minimum_price: String(terms.minimum_price ?? '0'),\n max_payout: String(terms.max_payout ?? '0'),\n max_debt: String(terms.max_debt ?? '0'),\n max_total_payout: String(terms.max_total_payout ?? '0'),\n },\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main enrichment function\n// ---------------------------------------------------------------------------\n\n/**\n * Enrich Sui bond configs into full BondsData objects.\n *\n * Reads each BondMarket object directly via `getObject` and computes\n * true_bill_price client-side using the same bond_math formulas as the\n * Move contract. Scale conversion: computed `true_bill_price` is u64\n * scaled by PRICE_DECIMALS = 1e8; the SDK stores `trueBondPrice` scaled\n * by 1e18 (legacy EVM format) → multiply by 1e10.\n */\nexport const enrichSuiBonds = async (\n bonds?: BillsConfig[],\n prices?: TokenPrices[],\n priceApiUrl?: string,\n): Promise<BondsData[]> => {\n if (!bonds || bonds?.length === 0) return []\n\n const client = getSuiClient()\n\n const enriched = await Promise.all(\n bonds.map(async (bond): Promise<BondsData | null> => {\n const marketAddr = bond.contractAddress[SUI_KEY]\n if (!marketAddr) return null\n try {\n const obj = await client.getObject({\n id: marketAddr,\n options: { showContent: true },\n })\n\n const fields = extractMarketFields(obj.data?.content)\n if (!fields) {\n console.warn(`[Sui] No content fields for market ${marketAddr}`)\n return null\n }\n\n let principalPrice = prices?.find((t) => t.tokenAddress.toLowerCase() === principalAddr)?.price!\n if (principalPrice === undefined) {\n try {\n const res = await axios.get(\n `${priceApiUrl}/realtime/price?token=${bond?.lpToken?.address?.[bond?.chainId]}&chain=${bond?.chainId}`,\n )\n console.log('Individual call for: ', bond.lpToken.symbol, '. Price: ', res.data.price)\n principalPrice = res.data.price ?? 0\n } catch {\n console.error('Failed to fetch price for: ', bond.lpToken.symbol)\n principalPrice = 0\n }\n }\n\n let payoutPrice = prices?.find((t) => t.tokenAddress.toLowerCase() === payoutAddr)?.price!\n if (payoutPrice === undefined) {\n try {\n // Missing token price, therefor make a single call to api to fetch it\n const res = await axios.get(\n `${priceApiUrl}/realtime/price?token=${bond?.earnToken?.address?.[bond?.chainId]}&chain=${bond?.chainId}`,\n )\n console.log('Individual call for: ', bond.earnToken.symbol, '. Price: ', res.data.price)\n payoutPrice = res.data.price ?? 0\n } catch {\n console.error('Failed to fetch price for: ', bond.earnToken.symbol)\n payoutPrice = 0\n }\n }\n\n const principalAddr = bond.lpToken.address[SUI_KEY]?.toLowerCase()\n const payoutAddr = bond.earnToken.address[SUI_KEY]?.toLowerCase()\n\n // ---------- Compute true_bill_price client-side ----------\n const payoutDecimals = bond.earnToken.decimals[SUI_KEY] ?? fields.payout_decimals\n const principalDecimals = bond.lpToken.decimals?.[SUI_KEY] ?? fields.principal_decimals\n\n const totalDebt = BigInt(fields.total_debt)\n const payoutInitialSupply = BigInt(fields.payout_token_initial_supply)\n const controlVariable = BigInt(fields.terms.fields.control_variable)\n const minimumPrice = BigInt(fields.terms.fields.minimum_price)\n const feeInPrincipalRaw = BigInt(fields.fee_in_principal)\n\n // Replicate calculate_current_debt → calculate_price → calculate_true_price\n const currentDebtPayout = valueOfToken(principalDecimals, payoutDecimals, totalDebt)\n const payoutScale = pow10(payoutDecimals)\n const principalScale = pow10(principalDecimals)\n\n const debtRatio = calculateDebtRatio(currentDebtPayout, payoutInitialSupply, payoutScale)\n const basePrice = calculateBondPrice(controlVariable, debtRatio, principalScale)\n const trueBillPriceU64 = calculateTruePrice(basePrice, feeInPrincipalRaw, minimumPrice)\n\n // Convert on-chain u64 (scaled 1e8) to the SDK's legacy 1e18 scale\n const trueBondPriceScaled = (trueBillPriceU64 * 10n ** 10n).toString()\n const trueBondPriceHuman = Number(trueBillPriceU64) / 1e8\n\n // Same formula as getRawDiscount / getRawBonus in state/bonds/utils.ts\n const discount = payoutPrice > 0 ? ((payoutPrice - principalPrice * trueBondPriceHuman) / payoutPrice) * 100 : 0\n const bonus = discount > 0 && discount < 100 ? (discount / (100 - discount)) * 100 : 0\n\n // Fees: u64 in PERCENTAGE_BASE (1e6) → divide by 10_000 for human %\n const feeInPayout = Number(fields.fee_in_payout) / 10_000\n const feeInPrincipal = Number(fields.fee_in_principal) / 10_000\n const trueBondPriceWithFee =\n feeInPayout < 100 ? trueBondPriceHuman * (1 / ((100 - feeInPayout) / 100)) : trueBondPriceHuman\n const discountWithFee =\n payoutPrice > 0 ? ((payoutPrice - principalPrice * trueBondPriceWithFee) / payoutPrice) * 100 : 0\n const bonusWithFee =\n discountWithFee > 0 && discountWithFee < 100 ? (discountWithFee / (100 - discountWithFee)) * 100 : 0\n\n const tokensRemaining = new BigNumber(fields.terms.fields.max_total_payout)\n .minus(new BigNumber(fields.total_payout_given))\n .div(new BigNumber(10).pow(payoutDecimals))\n .toString()\n\n return {\n ...bond,\n soldOut: fields.paused || fields.emergency_paused ? true : bond.soldOut,\n maxTotalPayout: fields.terms.fields.max_total_payout,\n totalPayoutGiven: fields.total_payout_given,\n maxPayout: fields.terms.fields.max_payout,\n tokensRemaining,\n showcaseTokenName: bond.earnToken.symbol,\n vestingTerm: Number(fields.terms.fields.vesting_term),\n vestingCliff: fields.cliff_period || undefined,\n feeInPayout,\n feeInPrincipal,\n trueBondPrices: [\n {\n trueBondPrice: trueBondPriceScaled,\n points: '0',\n discount,\n discountWithFee,\n bonus,\n bonusWithFee,\n boost: 0,\n },\n ],\n principalTokenPrice: principalPrice.toString(),\n payoutTokenPrice: payoutPrice.toString(),\n }\n } catch (e) {\n console.warn(`[Sui] Failed to read BondMarket for ${marketAddr}`, e)\n // Hide the bond from the list when on-chain data is unavailable —\n // showing a card with all zeros is confusing for users.\n return null\n }\n }),\n )\n return enriched.filter((b): b is BondsData => b !== null)\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { ChainId, BillArtCollection, BillVersion } from '@ape.swap/apeswap-lists';
|
|
2
|
+
import { SUI_PACKAGE_ID } from '../../constants/suiConstants.js';
|
|
3
|
+
|
|
4
|
+
// =============================================================================
|
|
5
|
+
// Sui bonds config — static bond listing for on-chain first architecture
|
|
6
|
+
// =============================================================================
|
|
7
|
+
//
|
|
8
|
+
// api-v2 and realtime-api do NOT support Sui. Bond listing comes from this
|
|
9
|
+
// static config. Enrichment (prices, discounts, vesting) is read on-chain via
|
|
10
|
+
// bond::market_info view function.
|
|
11
|
+
//
|
|
12
|
+
// TODO(sui): Replace placeholder addresses with real deployed market addresses.
|
|
13
|
+
// TODO(sui): Consider indexing BondMarketCreatedEvent for automatic market
|
|
14
|
+
// discovery instead of maintaining this static list.
|
|
15
|
+
//
|
|
16
|
+
// Call sites:
|
|
17
|
+
// - useBondsList.ts → getSuiBondsList()
|
|
18
|
+
// - useTokenPrices.ts → getSuiFallbackPrices()
|
|
19
|
+
const SUI_KEY = ChainId.SUI_MAINNET;
|
|
20
|
+
// TODO(sui): For mainnet launch, update these addresses:
|
|
21
|
+
// 1. SUI_BOND_MARKET_ADDRESS → mainnet bond market object address
|
|
22
|
+
// 2. SUI_PAYOUT_TOKEN_COIN_TYPE → mainnet payout token coin type (real token, not tAPE)
|
|
23
|
+
// 3. Add additional bond entries to SUI_BONDS_CONFIG for each mainnet market
|
|
24
|
+
// Also update SUI_PACKAGE_ID_MAINNET in suiConstants.ts.
|
|
25
|
+
// Bond market shared object address from testnet deploy (bond-id2, correct CV=89100 + 10% discount)
|
|
26
|
+
const SUI_BOND_MARKET_ADDRESS = '0x09b35be15cf3567d9a19a7aa35de08264549dc84d81fe30c5953c9d7fa5abaa3';
|
|
27
|
+
// tAPE payout token coin type
|
|
28
|
+
const SUI_PAYOUT_TOKEN_COIN_TYPE = `${SUI_PACKAGE_ID}::test_payout_token::TEST_PAYOUT_TOKEN`;
|
|
29
|
+
// tUSDC principal token coin type
|
|
30
|
+
const SUI_PRINCIPAL_TOKEN_COIN_TYPE = `${SUI_PACKAGE_ID}::test_principal_token::TEST_PRINCIPAL_TOKEN`;
|
|
31
|
+
// SUI native token
|
|
32
|
+
const SUI_NATIVE_TOKEN_ADDRESS = '0x2::sui::SUI';
|
|
33
|
+
const SUI_BONDS_CONFIG = [
|
|
34
|
+
{
|
|
35
|
+
index: 99101,
|
|
36
|
+
version: '2.0.0',
|
|
37
|
+
chainId: SUI_KEY,
|
|
38
|
+
billVersion: BillVersion.V2,
|
|
39
|
+
billType: 'reserve',
|
|
40
|
+
soldOut: false,
|
|
41
|
+
contractAddress: {
|
|
42
|
+
[SUI_KEY]: SUI_BOND_MARKET_ADDRESS,
|
|
43
|
+
},
|
|
44
|
+
billNnftAddress: {
|
|
45
|
+
[SUI_KEY]: `${SUI_PACKAGE_ID}::bond_nft::COLLECTION`,
|
|
46
|
+
},
|
|
47
|
+
lpToken: {
|
|
48
|
+
symbol: 'tUSDC',
|
|
49
|
+
address: {
|
|
50
|
+
[SUI_KEY]: SUI_PRINCIPAL_TOKEN_COIN_TYPE,
|
|
51
|
+
},
|
|
52
|
+
decimals: { [SUI_KEY]: 6 },
|
|
53
|
+
active: true,
|
|
54
|
+
},
|
|
55
|
+
earnToken: {
|
|
56
|
+
symbol: 'tAPE',
|
|
57
|
+
address: {
|
|
58
|
+
[SUI_KEY]: SUI_PAYOUT_TOKEN_COIN_TYPE,
|
|
59
|
+
},
|
|
60
|
+
decimals: { [SUI_KEY]: 8 },
|
|
61
|
+
active: true,
|
|
62
|
+
},
|
|
63
|
+
billArt: { collection: BillArtCollection.ApeBond_Collection1 },
|
|
64
|
+
shortDescription: 'Sui bond — on-chain first, no backend dependency.',
|
|
65
|
+
fullDescription: 'Sui bond operating in on-chain first mode. All market data (prices, discounts, vesting) is read directly from Move view functions. No api-v2 or realtime-api dependency.',
|
|
66
|
+
vestingTerm: 172800, // 48h (matching deployed contract)
|
|
67
|
+
vestingCliff: 300, // 5-minute cliff (CliffLinear vesting, matching deployed contract)
|
|
68
|
+
tags: ['Sui'],
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
// Fallback prices used until price-api.ape.bond supports Sui tokens.
|
|
72
|
+
// TODO(sui): Remove fallback prices when price-api returns Sui token prices.
|
|
73
|
+
// Update SUI and payout token prices to current values before mainnet launch.
|
|
74
|
+
const SUI_FALLBACK_PRICES = [
|
|
75
|
+
{
|
|
76
|
+
chainId: ChainId.SUI_MAINNET,
|
|
77
|
+
chainName: 'Sui',
|
|
78
|
+
tokenAddress: SUI_PRINCIPAL_TOKEN_COIN_TYPE,
|
|
79
|
+
name: 'Test USDC',
|
|
80
|
+
symbol: 'tUSDC',
|
|
81
|
+
price: 1.0,
|
|
82
|
+
priceSource: 'fallback',
|
|
83
|
+
updatedAt: 0,
|
|
84
|
+
secondsAgoUpdated: 0,
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
chainId: ChainId.SUI_MAINNET,
|
|
88
|
+
chainName: 'Sui',
|
|
89
|
+
tokenAddress: SUI_PAYOUT_TOKEN_COIN_TYPE,
|
|
90
|
+
name: 'Test APE',
|
|
91
|
+
symbol: 'tAPE',
|
|
92
|
+
price: 50.0, // testnet: inflated so bond shows a positive bonus
|
|
93
|
+
priceSource: 'fallback',
|
|
94
|
+
updatedAt: 0,
|
|
95
|
+
secondsAgoUpdated: 0,
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
chainId: ChainId.SUI_MAINNET,
|
|
99
|
+
chainName: 'Sui',
|
|
100
|
+
tokenAddress: SUI_NATIVE_TOKEN_ADDRESS,
|
|
101
|
+
name: 'Sui',
|
|
102
|
+
symbol: 'SUI',
|
|
103
|
+
price: 3.5,
|
|
104
|
+
priceSource: 'fallback',
|
|
105
|
+
updatedAt: 0,
|
|
106
|
+
secondsAgoUpdated: 0,
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
const getSuiBondsList = () => SUI_BONDS_CONFIG;
|
|
110
|
+
const getSuiFallbackPrices = () => SUI_FALLBACK_PRICES;
|
|
111
|
+
|
|
112
|
+
export { getSuiBondsList, getSuiFallbackPrices };
|
|
113
|
+
//# sourceMappingURL=suiBondsConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suiBondsConfig.js","sources":["../../../src/state/bonds/suiBondsConfig.ts"],"sourcesContent":["// =============================================================================\n// Sui bonds config — static bond listing for on-chain first architecture\n// =============================================================================\n//\n// api-v2 and realtime-api do NOT support Sui. Bond listing comes from this\n// static config. Enrichment (prices, discounts, vesting) is read on-chain via\n// bond::market_info view function.\n//\n// TODO(sui): Replace placeholder addresses with real deployed market addresses.\n// TODO(sui): Consider indexing BondMarketCreatedEvent for automatic market\n// discovery instead of maintaining this static list.\n//\n// Call sites:\n// - useBondsList.ts → getSuiBondsList()\n// - useTokenPrices.ts → getSuiFallbackPrices()\n\nimport { BillArtCollection, BillsConfig, BillVersion, ChainId } from '@ape.swap/apeswap-lists'\nimport { SUI_PACKAGE_ID } from '../../constants/suiConstants'\nimport type { TokenPrices } from '../tokenPrices/useTokenPrices'\n\nconst SUI_KEY = ChainId.SUI_MAINNET\n\n// TODO(sui): For mainnet launch, update these addresses:\n// 1. SUI_BOND_MARKET_ADDRESS → mainnet bond market object address\n// 2. SUI_PAYOUT_TOKEN_COIN_TYPE → mainnet payout token coin type (real token, not tAPE)\n// 3. Add additional bond entries to SUI_BONDS_CONFIG for each mainnet market\n// Also update SUI_PACKAGE_ID_MAINNET in suiConstants.ts.\n\n// Bond market shared object address from testnet deploy (bond-id2, correct CV=89100 + 10% discount)\nconst SUI_BOND_MARKET_ADDRESS = '0x09b35be15cf3567d9a19a7aa35de08264549dc84d81fe30c5953c9d7fa5abaa3'\n// tAPE payout token coin type\nconst SUI_PAYOUT_TOKEN_COIN_TYPE = `${SUI_PACKAGE_ID}::test_payout_token::TEST_PAYOUT_TOKEN`\n// tUSDC principal token coin type\nconst SUI_PRINCIPAL_TOKEN_COIN_TYPE = `${SUI_PACKAGE_ID}::test_principal_token::TEST_PRINCIPAL_TOKEN`\n// SUI native token\nconst SUI_NATIVE_TOKEN_ADDRESS = '0x2::sui::SUI'\n\nconst SUI_BONDS_CONFIG: BillsConfig[] = [\n {\n index: 99101,\n version: '2.0.0',\n chainId: SUI_KEY,\n billVersion: BillVersion.V2,\n billType: 'reserve',\n soldOut: false,\n contractAddress: {\n [SUI_KEY]: SUI_BOND_MARKET_ADDRESS,\n },\n billNnftAddress: {\n [SUI_KEY]: `${SUI_PACKAGE_ID}::bond_nft::COLLECTION`,\n },\n lpToken: {\n symbol: 'tUSDC',\n address: {\n [SUI_KEY]: SUI_PRINCIPAL_TOKEN_COIN_TYPE,\n },\n decimals: { [SUI_KEY]: 6 },\n active: true,\n },\n earnToken: {\n symbol: 'tAPE',\n address: {\n [SUI_KEY]: SUI_PAYOUT_TOKEN_COIN_TYPE,\n },\n decimals: { [SUI_KEY]: 8 },\n active: true,\n },\n billArt: { collection: BillArtCollection.ApeBond_Collection1 },\n shortDescription: 'Sui bond — on-chain first, no backend dependency.',\n fullDescription:\n 'Sui bond operating in on-chain first mode. All market data (prices, discounts, vesting) is read directly from Move view functions. No api-v2 or realtime-api dependency.',\n vestingTerm: 172800, // 48h (matching deployed contract)\n vestingCliff: 300, // 5-minute cliff (CliffLinear vesting, matching deployed contract)\n tags: ['Sui'],\n },\n]\n\n// Fallback prices used until price-api.ape.bond supports Sui tokens.\n// TODO(sui): Remove fallback prices when price-api returns Sui token prices.\n// Update SUI and payout token prices to current values before mainnet launch.\nconst SUI_FALLBACK_PRICES: TokenPrices[] = [\n {\n chainId: ChainId.SUI_MAINNET,\n chainName: 'Sui',\n tokenAddress: SUI_PRINCIPAL_TOKEN_COIN_TYPE,\n name: 'Test USDC',\n symbol: 'tUSDC',\n price: 1.0,\n priceSource: 'fallback',\n updatedAt: 0,\n secondsAgoUpdated: 0,\n },\n {\n chainId: ChainId.SUI_MAINNET,\n chainName: 'Sui',\n tokenAddress: SUI_PAYOUT_TOKEN_COIN_TYPE,\n name: 'Test APE',\n symbol: 'tAPE',\n price: 50.0, // testnet: inflated so bond shows a positive bonus\n priceSource: 'fallback',\n updatedAt: 0,\n secondsAgoUpdated: 0,\n },\n {\n chainId: ChainId.SUI_MAINNET,\n chainName: 'Sui',\n tokenAddress: SUI_NATIVE_TOKEN_ADDRESS,\n name: 'Sui',\n symbol: 'SUI',\n price: 3.5,\n priceSource: 'fallback',\n updatedAt: 0,\n secondsAgoUpdated: 0,\n },\n]\n\nexport const getSuiBondsList = (): BillsConfig[] => SUI_BONDS_CONFIG\n\nexport const getSuiFallbackPrices = (): TokenPrices[] => SUI_FALLBACK_PRICES\n"],"names":[],"mappings":"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"}
|