@ape.swap/bonds-sdk 7.0.4-test.1 → 7.0.4-test.3

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 (25) hide show
  1. package/dist/adapters/evm/state/fetchBondsDataEVM.js +43 -8
  2. package/dist/adapters/evm/state/fetchBondsDataEVM.js.map +1 -1
  3. package/dist/adapters/evm/state/fetchUsersBondsEVM.js +8 -2
  4. package/dist/adapters/evm/state/fetchUsersBondsEVM.js.map +1 -1
  5. package/dist/adapters/evm/state/lpStaking/useSoulZapLpStakingQuote.js +5 -1
  6. package/dist/adapters/evm/state/lpStaking/useSoulZapLpStakingQuote.js.map +1 -1
  7. package/dist/adapters/evm/views/lpStaking/BuyComponentLpStaking.js +26 -8
  8. package/dist/adapters/evm/views/lpStaking/BuyComponentLpStaking.js.map +1 -1
  9. package/dist/adapters/evm/views/lpStaking/YourLpStakingBondModal.js +1 -1
  10. package/dist/adapters/evm/views/lpStaking/YourLpStakingBondModal.js.map +1 -1
  11. package/dist/config/abi/lpStakingVault.json.js +14 -0
  12. package/dist/config/abi/lpStakingVault.json.js.map +1 -1
  13. package/dist/state/bonds/useBondsData.js +0 -1
  14. package/dist/state/bonds/useBondsData.js.map +1 -1
  15. package/dist/styles.css +1 -1
  16. package/dist/utils/displayHelpers.js +19 -0
  17. package/dist/utils/displayHelpers.js.map +1 -1
  18. package/dist/views/Bonds/utils.js +1 -0
  19. package/dist/views/Bonds/utils.js.map +1 -1
  20. package/dist/views/YourBonds/components/ClaimAll/ClaimAllModal.js +2 -1
  21. package/dist/views/YourBonds/components/ClaimAll/ClaimAllModal.js.map +1 -1
  22. package/dist/views/YourBondsModal/components/NFTImage/NFTImage.d.ts +2 -1
  23. package/dist/views/YourBondsModal/components/NFTImage/NFTImage.js +3 -4
  24. package/dist/views/YourBondsModal/components/NFTImage/NFTImage.js.map +1 -1
  25. package/package.json +1 -1
@@ -10,6 +10,7 @@ import { getBalanceNumber } from '../../../utils/getBalanceNumber.js';
10
10
  import { TIER_MAPPING } from '../../../state/tiers/tiers.js';
11
11
  import { resolveBondTokenPrices } from '../../../state/tokenPrices/resolveTokenPrice.js';
12
12
  import { fetchLpStakingLimits } from './lpStaking/fetchLpStakingLimits.js';
13
+ import LP_STAKING_VAULT_ABI from '../../../config/abi/lpStakingVault.json.js';
13
14
 
14
15
  /**
15
16
  * LP staking bonds have no bond contract. The buyer's bonus is a share of the staked position's value, set per campaign
@@ -19,17 +20,45 @@ import { fetchLpStakingLimits } from './lpStaking/fetchLpStakingLimits.js';
19
20
  */
20
21
  const fetchLpStakingBondsData = async (chainId, lpStakingBonds) => {
21
22
  const bondsWithCampaign = lpStakingBonds.filter((bond) => bond.lpStakingConfig?.adapter && bond.lpStakingConfig?.campaignId);
22
- const campaignCalls = bondsWithCampaign.map((bond) => ({
23
- address: bond.lpStakingConfig.adapter,
24
- name: 'campaigns',
25
- params: [bond.lpStakingConfig.campaignId],
23
+ // Per bond, from its adapter: the campaign, and whether ApeBond deposits are paused (DepositsArePaused)
24
+ const adapterCalls = bondsWithCampaign.flatMap((bond) => [
25
+ { address: bond.lpStakingConfig.adapter, name: 'campaigns', params: [bond.lpStakingConfig.campaignId] },
26
+ { address: bond.lpStakingConfig.adapter, name: 'depositsPaused' },
27
+ ]);
28
+ // And whether the vault the positions are staked in has deposits paused. The bond's contract is the vault. Read on its
29
+ // own: multicall fails as a whole, and this shouldn't take the campaigns down with it.
30
+ const vaultCalls = bondsWithCampaign.map((bond) => ({
31
+ address: bond.contractAddress[bond.chainId] ?? '',
32
+ name: 'depositsPaused',
26
33
  }));
27
- const campaigns = campaignCalls.length > 0 ? await multicall(chainId, APE_BOND_POSITION_ADAPTER_ABI, campaignCalls) : [];
34
+ const [adapterData, vaultData] = bondsWithCampaign.length > 0
35
+ ? await Promise.all([
36
+ multicall(chainId, APE_BOND_POSITION_ADAPTER_ABI, adapterCalls),
37
+ multicall(chainId, LP_STAKING_VAULT_ABI, vaultCalls),
38
+ ])
39
+ : [[], []];
40
+ const campaigns = bondsWithCampaign.map((_, i) => adapterData?.[i * 2]);
28
41
  // campaigns() → (enabled, downTicks, upTicks, toleranceTicks, bonusCliffSeconds, bonusBps, minBonusAmount)
42
+ // A bond that can't be bought: its campaign is disabled, or the adapter or the vault have deposits paused. A read
43
+ // that failed counts as not paused, so an RPC hiccup doesn't hide the bond (the deposit still reverts if it is).
44
+ const isSoldOut = (bond) => {
45
+ const i = bondsWithCampaign.indexOf(bond);
46
+ if (i === -1)
47
+ return false;
48
+ const campaign = campaigns[i];
49
+ const adapterPaused = adapterData?.[i * 2 + 1]?.[0] === true;
50
+ const vaultPaused = vaultData?.[i]?.[0] === true;
51
+ return (!!campaign && campaign[0] === false) || adapterPaused || vaultPaused;
52
+ };
29
53
  const getBonusBps = (bond) => {
30
54
  const campaign = campaigns?.[bondsWithCampaign.indexOf(bond)];
31
55
  return campaign ? Number(campaign[5]) : 0;
32
56
  };
57
+ // The bonus unlocks all at once after the campaign's cliff, so it's the bond's whole vesting term
58
+ const getBonusCliffSeconds = (bond) => {
59
+ const campaign = campaigns?.[bondsWithCampaign.indexOf(bond)];
60
+ return campaign ? Number(campaign[4]) : 0;
61
+ };
33
62
  const limits = await Promise.all(lpStakingBonds.map((bond) => bondsWithCampaign.includes(bond)
34
63
  ? fetchLpStakingLimits(chainId, bond, getBonusBps(bond)).catch((e) => {
35
64
  console.error(e);
@@ -43,7 +72,7 @@ const fetchLpStakingBondsData = async (chainId, lpStakingBonds) => {
43
72
  const discount = bonus > 0 ? (bonus / (100 + bonus)) * 100 : 0;
44
73
  return {
45
74
  ...bond,
46
- soldOut: false,
75
+ soldOut: isSoldOut(bond),
47
76
  feeInPayout: 0,
48
77
  feeInPrincipal: 0,
49
78
  trueBondPrices: [
@@ -63,7 +92,7 @@ const fetchLpStakingBondsData = async (chainId, lpStakingBonds) => {
63
92
  maxTotalPayout: limits[index]?.maxTotalPayout ?? '0',
64
93
  maxPayout: limits[index]?.maxPayout ?? '0',
65
94
  totalPayoutGiven: limits[index]?.totalPayoutGiven ?? '0',
66
- vestingTerm: 60 * 60 * 24 * 7, // 1 week
95
+ vestingTerm: getBonusCliffSeconds(bond),
67
96
  tierBoostRate: bond.tierBoostRate === undefined ? 1 : bond.tierBoostRate,
68
97
  };
69
98
  });
@@ -72,7 +101,13 @@ const fetchBondsDataEVM = async (chainId, bonds, apiUrl, tokenPrices) => {
72
101
  try {
73
102
  /** First we separate lpStakingBonds and bills. */
74
103
  const lpStakingBonds = bonds.filter((b) => !b.soldOut && b.billType === 'lpStaking');
75
- const lpStakingBondsData = lpStakingBonds.length > 0 ? await fetchLpStakingBondsData(chainId, lpStakingBonds) : [];
104
+ // Isolated, so a failed LP staking read (campaigns multicall, RPC) doesn't drop the chain's regular bonds
105
+ const lpStakingBondsData = lpStakingBonds.length > 0
106
+ ? await fetchLpStakingBondsData(chainId, lpStakingBonds).catch((e) => {
107
+ console.error('Error fetching LP staking bonds data:', e);
108
+ return [];
109
+ })
110
+ : [];
76
111
  const bills = bonds.filter((b) => !b.soldOut && b.billType !== 'lpStaking');
77
112
  const billIds = [];
78
113
  const billCalls = bills.flatMap((bill) => {
@@ -1 +1 @@
1
- {"version":3,"file":"fetchBondsDataEVM.js","sources":["../../../../src/adapters/evm/state/fetchBondsDataEVM.ts"],"sourcesContent":["import { BillsConfig, BillVersion, ChainId } from '@ape.swap/apeswap-lists'\nimport { TokenPrices } from '../../../state/tokenPrices/useTokenPrices'\nimport multicall from '../utils/multicall'\nimport BOND_2_4_0 from '../../../config/abi/BOND_2_4_0.json'\nimport ERC20ABI from '../../../config/abi/erc20.json'\nimport APE_BOND_POSITION_ADAPTER_ABI from '../../../config/abi/apeBondPositionAdapter.json'\nimport chunk from 'lodash-es/chunk.js'\nimport {\n getBonusWithFee,\n getDiscountWithFee,\n getRawBonus,\n getRawDiscount,\n} from '../../../state/bonds/fetchBondsData/bondPricing'\nimport { formatUnits } from '../../../utils/fixedPoint'\nimport { getBalanceNumber } from '../../../utils/getBalanceNumber'\nimport { BondsData, TrueBondPrices } from '../../../types/bonds'\nimport { TIER_MAPPING } from '../../../state/tiers/tiers'\nimport { resolveBondTokenPrices } from '../../../state/tokenPrices/resolveTokenPrice'\nimport { fetchLpStakingLimits } from './lpStaking/fetchLpStakingLimits'\n\n/**\n * LP staking bonds have no bond contract. The buyer's bonus is a share of the staked position's value, set per campaign\n * on the bond's adapter: `campaigns(campaignId).bonusBps`. It's exposed as the bond's bonus so the UI shows it like any\n * other bond's. The per-purchase and total limits come from the pool's price guard and the bonus escrow\n * (fetchLpStakingLimits). Prices are still placeholder data.\n */\nconst fetchLpStakingBondsData = async (chainId: number, lpStakingBonds: BillsConfig[]): Promise<BondsData[]> => {\n const bondsWithCampaign = lpStakingBonds.filter(\n (bond) => bond.lpStakingConfig?.adapter && bond.lpStakingConfig?.campaignId,\n )\n const campaignCalls = bondsWithCampaign.map((bond) => ({\n address: bond.lpStakingConfig!.adapter,\n name: 'campaigns',\n params: [bond.lpStakingConfig!.campaignId],\n }))\n const campaigns =\n campaignCalls.length > 0 ? await multicall(chainId, APE_BOND_POSITION_ADAPTER_ABI, campaignCalls) : []\n\n // campaigns() → (enabled, downTicks, upTicks, toleranceTicks, bonusCliffSeconds, bonusBps, minBonusAmount)\n const getBonusBps = (bond: BillsConfig) => {\n const campaign = campaigns?.[bondsWithCampaign.indexOf(bond)]\n return campaign ? Number(campaign[5]) : 0\n }\n const limits = await Promise.all(\n lpStakingBonds.map((bond) =>\n bondsWithCampaign.includes(bond)\n ? fetchLpStakingLimits(chainId, bond, getBonusBps(bond)).catch((e) => {\n console.error(e)\n return undefined\n })\n : undefined,\n ),\n )\n\n return lpStakingBonds.map((bond, index) => {\n const bonusBps = getBonusBps(bond)\n const bonus = bonusBps / 100 // e.g. 1,000 bps → 10 %\n // The bonus is computed on the position value after fees, so there's no separate \"with fee\" figure\n const discount = bonus > 0 ? (bonus / (100 + bonus)) * 100 : 0\n return {\n ...bond,\n soldOut: false,\n feeInPayout: 0,\n feeInPrincipal: 0,\n trueBondPrices: [\n {\n points: '0',\n boost: 0,\n trueBondPrice: '0',\n bonus,\n bonusWithFee: bonus,\n discount,\n discountWithFee: discount,\n },\n ],\n principalTokenPrice: '0',\n payoutTokenPrice: '0',\n tokensRemaining: limits[index]?.tokensRemaining ?? '0',\n maxTotalPayout: limits[index]?.maxTotalPayout ?? '0',\n maxPayout: limits[index]?.maxPayout ?? '0',\n totalPayoutGiven: limits[index]?.totalPayoutGiven ?? '0',\n vestingTerm: 60 * 60 * 24 * 7, // 1 week\n tierBoostRate: bond.tierBoostRate === undefined ? 1 : bond.tierBoostRate,\n }\n })\n}\n\nexport const fetchBondsDataEVM = async (\n chainId: number,\n bonds: BillsConfig[],\n apiUrl: string,\n tokenPrices?: TokenPrices[],\n) => {\n try {\n /** First we separate lpStakingBonds and bills. */\n const lpStakingBonds = bonds.filter((b) => !b.soldOut && b.billType === 'lpStaking')\n const lpStakingBondsData = lpStakingBonds.length > 0 ? await fetchLpStakingBondsData(chainId, lpStakingBonds) : []\n\n const bills = bonds.filter((b) => !b.soldOut && b.billType !== 'lpStaking')\n const billIds: number[] = []\n const billCalls = bills.flatMap((bill) => {\n billIds.push(bill.index)\n return [\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: bill.billVersion === BillVersion.V4 ? 'trueBondPrices' : 'trueBillPrice()',\n },\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: 'totalPayoutGiven',\n },\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: 'terms',\n },\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: bill.billVersion !== BillVersion.V1 ? 'getMaxTotalPayout' : 'maxTotalPayout',\n },\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: 'feeInPayout',\n },\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: 'feeInPrincipal',\n },\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: 'paused',\n },\n // keep custom treasury at the very last position\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: 'customTreasury',\n },\n ]\n })\n const vals = await multicall(chainId, BOND_2_4_0, billCalls)\n\n // The following lines basically grab the values from customTreasury returned from bills contract and then,\n // appends the treasury contract's balance to each bill's chunk\n\n // appendIndex value assumes customTreasury will be at the end of the billCalls array\n const appendIndex = billCalls.length / bills.length\n const treasuryAddresses = vals\n .filter((_: any, i: number) => (i % appendIndex) + 1 === appendIndex)\n .map((customTreasury: string[]) => customTreasury[0])\n const treasuryBalanceCalls = treasuryAddresses.map((treasuryAddress: string, i: number) => ({\n address: bills?.[i]?.earnToken?.address?.[chainId as ChainId] ?? '',\n name: 'balanceOf',\n params: [treasuryAddress],\n }))\n const treasuryBalances = await multicall(chainId, ERC20ABI, treasuryBalanceCalls)\n const updatedVals = vals.reduce((acc: any, val: any, index: number) => {\n acc.push(val)\n if ((index + 1) % appendIndex === 0) {\n const pos = (index + 1) / appendIndex\n // balanceOf has a single output, so multicall wraps it as [balance] — unwrap it\n acc.push(treasuryBalances[pos - 1][0])\n }\n return acc\n }, [])\n\n const chunkSize = updatedVals?.length / bills?.length\n const chunkedBills = chunk(updatedVals, chunkSize)\n\n const regularBondsData = await Promise.all(\n chunkedBills?.map(async (chunk, index) => {\n const bill = bills?.find((bill) => bill?.index === billIds[index]) as BillsConfig\n\n const { lpPrice, earnTokenPrice } = await resolveBondTokenPrices(bill, tokenPrices)\n\n const [\n trueBillPriceFromChunk,\n totalPayoutGiven,\n terms,\n maxTotalPayout,\n feeInPayoutRaw,\n feeInPrincipalRaw,\n paused,\n ,\n customTreasuryBalance,\n ] = chunk as any\n const trueBillPrice = trueBillPriceFromChunk\n\n const feeInPayout = Number(feeInPayoutRaw / 10000)\n const feeInPrincipal = Number(feeInPrincipalRaw / 10000)\n const tierBoostRate = bill.tierBoostRate === undefined ? 1 : bill.tierBoostRate\n const [, vestingTerm, , maxPayout] = terms\n const tokensRemaining = Number(\n formatUnits(\n BigInt(maxTotalPayout ?? '0') - BigInt(totalPayoutGiven),\n bill?.earnToken.decimals[bill?.chainId] ?? 18,\n ),\n )\n const treasuryBalance = customTreasuryBalance\n ? getBalanceNumber(customTreasuryBalance, bill?.earnToken?.decimals?.[bill?.chainId] ?? 18)\n : null\n\n let trueBondPrices: TrueBondPrices[] = []\n if (bill?.billVersion === BillVersion.V4) {\n trueBondPrices = trueBillPrice[0].map((data: any) => {\n return {\n points: data?.points?.toString(),\n trueBondPrice: data?.trueBondPrice.toString(),\n discount: getRawDiscount(data?.trueBondPrice.toString(), lpPrice, earnTokenPrice),\n bonus: getRawBonus(data?.trueBondPrice.toString(), lpPrice, earnTokenPrice),\n discountWithFee: getDiscountWithFee(\n feeInPayout,\n tierBoostRate,\n data?.trueBondPrice.toString(),\n lpPrice,\n earnTokenPrice,\n ),\n bonusWithFee: getBonusWithFee(\n feeInPayout,\n tierBoostRate,\n data?.trueBondPrice.toString(),\n lpPrice,\n earnTokenPrice,\n ),\n boost: TIER_MAPPING[data?.points?.toString() as keyof typeof TIER_MAPPING],\n }\n })\n } else {\n const bonus = getRawBonus(trueBillPrice, lpPrice, earnTokenPrice)\n const bonusWithFee = getBonusWithFee(feeInPayout, tierBoostRate, trueBillPrice, lpPrice, earnTokenPrice)\n const discount = getRawDiscount(trueBillPrice, lpPrice, earnTokenPrice)\n const discountWithFee = getDiscountWithFee(feeInPayout, tierBoostRate, trueBillPrice, lpPrice, earnTokenPrice)\n trueBondPrices = [\n {\n points: '0',\n boost: 0,\n trueBondPrice: trueBillPrice.toString(),\n bonus,\n bonusWithFee,\n discount,\n discountWithFee,\n },\n ]\n }\n const cleanedData: BondsData = {\n ...bill,\n soldOut: paused[0] ? true : bill.soldOut,\n feeInPayout,\n feeInPrincipal,\n showcaseTokenName: bill?.showcaseToken?.symbol ?? bill?.earnToken.symbol ?? '',\n trueBondPrices,\n principalTokenPrice: lpPrice?.toString(),\n payoutTokenPrice: earnTokenPrice?.toString(),\n tokensRemaining:\n treasuryBalance !== null\n ? Math.min(treasuryBalance, tokensRemaining).toString()\n : tokensRemaining.toString(),\n maxTotalPayout: maxTotalPayout?.toString(),\n maxPayout: maxPayout?.toString(),\n totalPayoutGiven: totalPayoutGiven?.toString(),\n vestingTerm: typeof vestingTerm === 'number' ? vestingTerm : parseInt(vestingTerm),\n tierBoostRate: bill.tierBoostRate === undefined ? 1 : bill.tierBoostRate,\n }\n return cleanedData\n }),\n )\n return [...lpStakingBondsData, ...regularBondsData]\n } catch (e) {\n console.error(e)\n reportError({\n apiUrl,\n error: e,\n extraInfo: { type: 'getBondsData', e },\n })\n return []\n }\n}\n"],"names":["BOND_2_4_0","ERC20ABI"],"mappings":";;;;;;;;;;;;;AAoBA;;;;;AAKG;AACH,MAAM,uBAAuB,GAAG,OAAO,OAAe,EAAE,cAA6B,KAA0B;IAC7G,MAAM,iBAAiB,GAAG,cAAc,CAAC,MAAM,CAC7C,CAAC,IAAI,KAAK,IAAI,CAAC,eAAe,EAAE,OAAO,IAAI,IAAI,CAAC,eAAe,EAAE,UAAU,CAC5E;IACD,MAAM,aAAa,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM;AACrD,QAAA,OAAO,EAAE,IAAI,CAAC,eAAgB,CAAC,OAAO;AACtC,QAAA,IAAI,EAAE,WAAW;AACjB,QAAA,MAAM,EAAE,CAAC,IAAI,CAAC,eAAgB,CAAC,UAAU,CAAC;AAC3C,KAAA,CAAC,CAAC;IACH,MAAM,SAAS,GACb,aAAa,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,6BAA6B,EAAE,aAAa,CAAC,GAAG,EAAE;;AAGxG,IAAA,MAAM,WAAW,GAAG,CAAC,IAAiB,KAAI;AACxC,QAAA,MAAM,QAAQ,GAAG,SAAS,GAAG,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC7D,QAAA,OAAO,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC3C,IAAA,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,KACtB,iBAAiB,CAAC,QAAQ,CAAC,IAAI;AAC7B,UAAE,oBAAoB,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAI;AACjE,YAAA,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AAChB,YAAA,OAAO,SAAS;AAClB,QAAA,CAAC;AACH,UAAE,SAAS,CACd,CACF;IAED,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,KAAI;AACxC,QAAA,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC;AAClC,QAAA,MAAM,KAAK,GAAG,QAAQ,GAAG,GAAG,CAAA;;QAE5B,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,GAAG,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC;QAC9D,OAAO;AACL,YAAA,GAAG,IAAI;AACP,YAAA,OAAO,EAAE,KAAK;AACd,YAAA,WAAW,EAAE,CAAC;AACd,YAAA,cAAc,EAAE,CAAC;AACjB,YAAA,cAAc,EAAE;AACd,gBAAA;AACE,oBAAA,MAAM,EAAE,GAAG;AACX,oBAAA,KAAK,EAAE,CAAC;AACR,oBAAA,aAAa,EAAE,GAAG;oBAClB,KAAK;AACL,oBAAA,YAAY,EAAE,KAAK;oBACnB,QAAQ;AACR,oBAAA,eAAe,EAAE,QAAQ;AAC1B,iBAAA;AACF,aAAA;AACD,YAAA,mBAAmB,EAAE,GAAG;AACxB,YAAA,gBAAgB,EAAE,GAAG;YACrB,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,eAAe,IAAI,GAAG;YACtD,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,cAAc,IAAI,GAAG;YACpD,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,IAAI,GAAG;YAC1C,gBAAgB,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,gBAAgB,IAAI,GAAG;YACxD,WAAW,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;AAC7B,YAAA,aAAa,EAAE,IAAI,CAAC,aAAa,KAAK,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa;SACzE;AACH,IAAA,CAAC,CAAC;AACJ,CAAC;AAEM,MAAM,iBAAiB,GAAG,OAC/B,OAAe,EACf,KAAoB,EACpB,MAAc,EACd,WAA2B,KACzB;AACF,IAAA,IAAI;;QAEF,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,QAAQ,KAAK,WAAW,CAAC;QACpF,MAAM,kBAAkB,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,uBAAuB,CAAC,OAAO,EAAE,cAAc,CAAC,GAAG,EAAE;QAElH,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,QAAQ,KAAK,WAAW,CAAC;QAC3E,MAAM,OAAO,GAAa,EAAE;QAC5B,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;AACvC,YAAA,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YACxB,OAAO;AACL,gBAAA;oBACE,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;AACjD,oBAAA,IAAI,EAAE,IAAI,CAAC,WAAW,KAAK,WAAW,CAAC,EAAE,GAAG,gBAAgB,GAAG,iBAAiB;AACjF,iBAAA;AACD,gBAAA;oBACE,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;AACjD,oBAAA,IAAI,EAAE,kBAAkB;AACzB,iBAAA;AACD,gBAAA;oBACE,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;AACjD,oBAAA,IAAI,EAAE,OAAO;AACd,iBAAA;AACD,gBAAA;oBACE,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;AACjD,oBAAA,IAAI,EAAE,IAAI,CAAC,WAAW,KAAK,WAAW,CAAC,EAAE,GAAG,mBAAmB,GAAG,gBAAgB;AACnF,iBAAA;AACD,gBAAA;oBACE,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;AACjD,oBAAA,IAAI,EAAE,aAAa;AACpB,iBAAA;AACD,gBAAA;oBACE,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;AACjD,oBAAA,IAAI,EAAE,gBAAgB;AACvB,iBAAA;AACD,gBAAA;oBACE,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;AACjD,oBAAA,IAAI,EAAE,QAAQ;AACf,iBAAA;;AAED,gBAAA;oBACE,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;AACjD,oBAAA,IAAI,EAAE,gBAAgB;AACvB,iBAAA;aACF;AACH,QAAA,CAAC,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,EAAEA,QAAU,EAAE,SAAS,CAAC;;;;QAM5D,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;QACnD,MAAM,iBAAiB,GAAG;AACvB,aAAA,MAAM,CAAC,CAAC,CAAM,EAAE,CAAS,KAAK,CAAC,CAAC,GAAG,WAAW,IAAI,CAAC,KAAK,WAAW;aACnE,GAAG,CAAC,CAAC,cAAwB,KAAK,cAAc,CAAC,CAAC,CAAC,CAAC;AACvD,QAAA,MAAM,oBAAoB,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,eAAuB,EAAE,CAAS,MAAM;AAC1F,YAAA,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,GAAG,OAAkB,CAAC,IAAI,EAAE;AACnE,YAAA,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,CAAC,eAAe,CAAC;AAC1B,SAAA,CAAC,CAAC;QACH,MAAM,gBAAgB,GAAG,MAAM,SAAS,CAAC,OAAO,EAAEC,QAAQ,EAAE,oBAAoB,CAAC;AACjF,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAQ,EAAE,GAAQ,EAAE,KAAa,KAAI;AACpE,YAAA,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;YACb,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,WAAW,KAAK,CAAC,EAAE;gBACnC,MAAM,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,WAAW;;AAErC,gBAAA,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACxC;AACA,YAAA,OAAO,GAAG;QACZ,CAAC,EAAE,EAAE,CAAC;QAEN,MAAM,SAAS,GAAG,WAAW,EAAE,MAAM,GAAG,KAAK,EAAE,MAAM;QACrD,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC;AAElD,QAAA,MAAM,gBAAgB,GAAG,MAAM,OAAO,CAAC,GAAG,CACxC,YAAY,EAAE,GAAG,CAAC,OAAO,KAAK,EAAE,KAAK,KAAI;YACvC,MAAM,IAAI,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,KAAK,CAAC,CAAgB;AAEjF,YAAA,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,MAAM,sBAAsB,CAAC,IAAI,EAAE,WAAW,CAAC;YAEnF,MAAM,CACJ,sBAAsB,EACtB,gBAAgB,EAChB,KAAK,EACL,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,MAAM,IAEN,qBAAqB,EACtB,GAAG,KAAY;YAChB,MAAM,aAAa,GAAG,sBAAsB;YAE5C,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,GAAG,KAAK,CAAC;YAClD,MAAM,cAAc,GAAG,MAAM,CAAC,iBAAiB,GAAG,KAAK,CAAC;AACxD,YAAA,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,KAAK,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa;YAC/E,MAAM,GAAG,WAAW,IAAI,SAAS,CAAC,GAAG,KAAK;AAC1C,YAAA,MAAM,eAAe,GAAG,MAAM,CAC5B,WAAW,CACT,MAAM,CAAC,cAAc,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,gBAAgB,CAAC,EACxD,IAAI,EAAE,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAC9C,CACF;YACD,MAAM,eAAe,GAAG;AACtB,kBAAE,gBAAgB,CAAC,qBAAqB,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,GAAG,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE;kBACxF,IAAI;YAER,IAAI,cAAc,GAAqB,EAAE;YACzC,IAAI,IAAI,EAAE,WAAW,KAAK,WAAW,CAAC,EAAE,EAAE;gBACxC,cAAc,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAS,KAAI;oBAClD,OAAO;AACL,wBAAA,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE;AAChC,wBAAA,aAAa,EAAE,IAAI,EAAE,aAAa,CAAC,QAAQ,EAAE;AAC7C,wBAAA,QAAQ,EAAE,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,cAAc,CAAC;AACjF,wBAAA,KAAK,EAAE,WAAW,CAAC,IAAI,EAAE,aAAa,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,cAAc,CAAC;AAC3E,wBAAA,eAAe,EAAE,kBAAkB,CACjC,WAAW,EACX,aAAa,EACb,IAAI,EAAE,aAAa,CAAC,QAAQ,EAAE,EAC9B,OAAO,EACP,cAAc,CACf;AACD,wBAAA,YAAY,EAAE,eAAe,CAC3B,WAAW,EACX,aAAa,EACb,IAAI,EAAE,aAAa,CAAC,QAAQ,EAAE,EAC9B,OAAO,EACP,cAAc,CACf;wBACD,KAAK,EAAE,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAA+B,CAAC;qBAC3E;AACH,gBAAA,CAAC,CAAC;YACJ;iBAAO;gBACL,MAAM,KAAK,GAAG,WAAW,CAAC,aAAa,EAAE,OAAO,EAAE,cAAc,CAAC;AACjE,gBAAA,MAAM,YAAY,GAAG,eAAe,CAAC,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,CAAC;gBACxG,MAAM,QAAQ,GAAG,cAAc,CAAC,aAAa,EAAE,OAAO,EAAE,cAAc,CAAC;AACvE,gBAAA,MAAM,eAAe,GAAG,kBAAkB,CAAC,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,CAAC;AAC9G,gBAAA,cAAc,GAAG;AACf,oBAAA;AACE,wBAAA,MAAM,EAAE,GAAG;AACX,wBAAA,KAAK,EAAE,CAAC;AACR,wBAAA,aAAa,EAAE,aAAa,CAAC,QAAQ,EAAE;wBACvC,KAAK;wBACL,YAAY;wBACZ,QAAQ;wBACR,eAAe;AAChB,qBAAA;iBACF;YACH;AACA,YAAA,MAAM,WAAW,GAAc;AAC7B,gBAAA,GAAG,IAAI;AACP,gBAAA,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,OAAO;gBACxC,WAAW;gBACX,cAAc;AACd,gBAAA,iBAAiB,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,IAAI,IAAI,EAAE,SAAS,CAAC,MAAM,IAAI,EAAE;gBAC9E,cAAc;AACd,gBAAA,mBAAmB,EAAE,OAAO,EAAE,QAAQ,EAAE;AACxC,gBAAA,gBAAgB,EAAE,cAAc,EAAE,QAAQ,EAAE;gBAC5C,eAAe,EACb,eAAe,KAAK;sBAChB,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC,QAAQ;AACrD,sBAAE,eAAe,CAAC,QAAQ,EAAE;AAChC,gBAAA,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE;AAC1C,gBAAA,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE;AAChC,gBAAA,gBAAgB,EAAE,gBAAgB,EAAE,QAAQ,EAAE;AAC9C,gBAAA,WAAW,EAAE,OAAO,WAAW,KAAK,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC;AAClF,gBAAA,aAAa,EAAE,IAAI,CAAC,aAAa,KAAK,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa;aACzE;AACD,YAAA,OAAO,WAAW;QACpB,CAAC,CAAC,CACH;AACD,QAAA,OAAO,CAAC,GAAG,kBAAkB,EAAE,GAAG,gBAAgB,CAAC;IACrD;IAAE,OAAO,CAAC,EAAE;AACV,QAAA,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AAChB,QAAA,WAAW,CAAC;YACV,MAAM;AACN,YAAA,KAAK,EAAE,CAAC;AACR,YAAA,SAAS,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,EAAE;AACvC,SAAA,CAAC;AACF,QAAA,OAAO,EAAE;IACX;AACF;;;;"}
1
+ {"version":3,"file":"fetchBondsDataEVM.js","sources":["../../../../src/adapters/evm/state/fetchBondsDataEVM.ts"],"sourcesContent":["import { BillsConfig, BillVersion, ChainId } from '@ape.swap/apeswap-lists'\nimport { TokenPrices } from '../../../state/tokenPrices/useTokenPrices'\nimport multicall from '../utils/multicall'\nimport BOND_2_4_0 from '../../../config/abi/BOND_2_4_0.json'\nimport ERC20ABI from '../../../config/abi/erc20.json'\nimport APE_BOND_POSITION_ADAPTER_ABI from '../../../config/abi/apeBondPositionAdapter.json'\nimport chunk from 'lodash-es/chunk.js'\nimport {\n getBonusWithFee,\n getDiscountWithFee,\n getRawBonus,\n getRawDiscount,\n} from '../../../state/bonds/fetchBondsData/bondPricing'\nimport { formatUnits } from '../../../utils/fixedPoint'\nimport { getBalanceNumber } from '../../../utils/getBalanceNumber'\nimport { BondsData, TrueBondPrices } from '../../../types/bonds'\nimport { TIER_MAPPING } from '../../../state/tiers/tiers'\nimport { resolveBondTokenPrices } from '../../../state/tokenPrices/resolveTokenPrice'\nimport { fetchLpStakingLimits } from './lpStaking/fetchLpStakingLimits'\nimport LP_STAKING_VAULT_ABI from '../../../config/abi/lpStakingVault.json'\n\n/**\n * LP staking bonds have no bond contract. The buyer's bonus is a share of the staked position's value, set per campaign\n * on the bond's adapter: `campaigns(campaignId).bonusBps`. It's exposed as the bond's bonus so the UI shows it like any\n * other bond's. The per-purchase and total limits come from the pool's price guard and the bonus escrow\n * (fetchLpStakingLimits). Prices are still placeholder data.\n */\nconst fetchLpStakingBondsData = async (chainId: number, lpStakingBonds: BillsConfig[]): Promise<BondsData[]> => {\n const bondsWithCampaign = lpStakingBonds.filter(\n (bond) => bond.lpStakingConfig?.adapter && bond.lpStakingConfig?.campaignId,\n )\n // Per bond, from its adapter: the campaign, and whether ApeBond deposits are paused (DepositsArePaused)\n const adapterCalls = bondsWithCampaign.flatMap((bond) => [\n { address: bond.lpStakingConfig!.adapter, name: 'campaigns', params: [bond.lpStakingConfig!.campaignId] },\n { address: bond.lpStakingConfig!.adapter, name: 'depositsPaused' },\n ])\n // And whether the vault the positions are staked in has deposits paused. The bond's contract is the vault. Read on its\n // own: multicall fails as a whole, and this shouldn't take the campaigns down with it.\n const vaultCalls = bondsWithCampaign.map((bond) => ({\n address: bond.contractAddress[bond.chainId] ?? '',\n name: 'depositsPaused',\n }))\n const [adapterData, vaultData] =\n bondsWithCampaign.length > 0\n ? await Promise.all([\n multicall(chainId, APE_BOND_POSITION_ADAPTER_ABI, adapterCalls),\n multicall(chainId, LP_STAKING_VAULT_ABI, vaultCalls),\n ])\n : [[], []]\n const campaigns = bondsWithCampaign.map((_, i) => adapterData?.[i * 2])\n\n // campaigns() → (enabled, downTicks, upTicks, toleranceTicks, bonusCliffSeconds, bonusBps, minBonusAmount)\n // A bond that can't be bought: its campaign is disabled, or the adapter or the vault have deposits paused. A read\n // that failed counts as not paused, so an RPC hiccup doesn't hide the bond (the deposit still reverts if it is).\n const isSoldOut = (bond: BillsConfig) => {\n const i = bondsWithCampaign.indexOf(bond)\n if (i === -1) return false\n const campaign = campaigns[i]\n const adapterPaused = adapterData?.[i * 2 + 1]?.[0] === true\n const vaultPaused = vaultData?.[i]?.[0] === true\n return (!!campaign && campaign[0] === false) || adapterPaused || vaultPaused\n }\n const getBonusBps = (bond: BillsConfig) => {\n const campaign = campaigns?.[bondsWithCampaign.indexOf(bond)]\n return campaign ? Number(campaign[5]) : 0\n }\n // The bonus unlocks all at once after the campaign's cliff, so it's the bond's whole vesting term\n const getBonusCliffSeconds = (bond: BillsConfig) => {\n const campaign = campaigns?.[bondsWithCampaign.indexOf(bond)]\n return campaign ? Number(campaign[4]) : 0\n }\n const limits = await Promise.all(\n lpStakingBonds.map((bond) =>\n bondsWithCampaign.includes(bond)\n ? fetchLpStakingLimits(chainId, bond, getBonusBps(bond)).catch((e) => {\n console.error(e)\n return undefined\n })\n : undefined,\n ),\n )\n\n return lpStakingBonds.map((bond, index) => {\n const bonusBps = getBonusBps(bond)\n const bonus = bonusBps / 100 // e.g. 1,000 bps → 10 %\n // The bonus is computed on the position value after fees, so there's no separate \"with fee\" figure\n const discount = bonus > 0 ? (bonus / (100 + bonus)) * 100 : 0\n return {\n ...bond,\n soldOut: isSoldOut(bond),\n feeInPayout: 0,\n feeInPrincipal: 0,\n trueBondPrices: [\n {\n points: '0',\n boost: 0,\n trueBondPrice: '0',\n bonus,\n bonusWithFee: bonus,\n discount,\n discountWithFee: discount,\n },\n ],\n principalTokenPrice: '0',\n payoutTokenPrice: '0',\n tokensRemaining: limits[index]?.tokensRemaining ?? '0',\n maxTotalPayout: limits[index]?.maxTotalPayout ?? '0',\n maxPayout: limits[index]?.maxPayout ?? '0',\n totalPayoutGiven: limits[index]?.totalPayoutGiven ?? '0',\n vestingTerm: getBonusCliffSeconds(bond),\n tierBoostRate: bond.tierBoostRate === undefined ? 1 : bond.tierBoostRate,\n }\n })\n}\n\nexport const fetchBondsDataEVM = async (\n chainId: number,\n bonds: BillsConfig[],\n apiUrl: string,\n tokenPrices?: TokenPrices[],\n) => {\n try {\n /** First we separate lpStakingBonds and bills. */\n const lpStakingBonds = bonds.filter((b) => !b.soldOut && b.billType === 'lpStaking')\n // Isolated, so a failed LP staking read (campaigns multicall, RPC) doesn't drop the chain's regular bonds\n const lpStakingBondsData =\n lpStakingBonds.length > 0\n ? await fetchLpStakingBondsData(chainId, lpStakingBonds).catch((e) => {\n console.error('Error fetching LP staking bonds data:', e)\n return []\n })\n : []\n\n const bills = bonds.filter((b) => !b.soldOut && b.billType !== 'lpStaking')\n const billIds: number[] = []\n const billCalls = bills.flatMap((bill) => {\n billIds.push(bill.index)\n return [\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: bill.billVersion === BillVersion.V4 ? 'trueBondPrices' : 'trueBillPrice()',\n },\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: 'totalPayoutGiven',\n },\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: 'terms',\n },\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: bill.billVersion !== BillVersion.V1 ? 'getMaxTotalPayout' : 'maxTotalPayout',\n },\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: 'feeInPayout',\n },\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: 'feeInPrincipal',\n },\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: 'paused',\n },\n // keep custom treasury at the very last position\n {\n address: bill.contractAddress[bill.chainId] ?? '',\n name: 'customTreasury',\n },\n ]\n })\n const vals = await multicall(chainId, BOND_2_4_0, billCalls)\n\n // The following lines basically grab the values from customTreasury returned from bills contract and then,\n // appends the treasury contract's balance to each bill's chunk\n\n // appendIndex value assumes customTreasury will be at the end of the billCalls array\n const appendIndex = billCalls.length / bills.length\n const treasuryAddresses = vals\n .filter((_: any, i: number) => (i % appendIndex) + 1 === appendIndex)\n .map((customTreasury: string[]) => customTreasury[0])\n const treasuryBalanceCalls = treasuryAddresses.map((treasuryAddress: string, i: number) => ({\n address: bills?.[i]?.earnToken?.address?.[chainId as ChainId] ?? '',\n name: 'balanceOf',\n params: [treasuryAddress],\n }))\n const treasuryBalances = await multicall(chainId, ERC20ABI, treasuryBalanceCalls)\n const updatedVals = vals.reduce((acc: any, val: any, index: number) => {\n acc.push(val)\n if ((index + 1) % appendIndex === 0) {\n const pos = (index + 1) / appendIndex\n // balanceOf has a single output, so multicall wraps it as [balance] — unwrap it\n acc.push(treasuryBalances[pos - 1][0])\n }\n return acc\n }, [])\n\n const chunkSize = updatedVals?.length / bills?.length\n const chunkedBills = chunk(updatedVals, chunkSize)\n\n const regularBondsData = await Promise.all(\n chunkedBills?.map(async (chunk, index) => {\n const bill = bills?.find((bill) => bill?.index === billIds[index]) as BillsConfig\n\n const { lpPrice, earnTokenPrice } = await resolveBondTokenPrices(bill, tokenPrices)\n\n const [\n trueBillPriceFromChunk,\n totalPayoutGiven,\n terms,\n maxTotalPayout,\n feeInPayoutRaw,\n feeInPrincipalRaw,\n paused,\n ,\n customTreasuryBalance,\n ] = chunk as any\n const trueBillPrice = trueBillPriceFromChunk\n\n const feeInPayout = Number(feeInPayoutRaw / 10000)\n const feeInPrincipal = Number(feeInPrincipalRaw / 10000)\n const tierBoostRate = bill.tierBoostRate === undefined ? 1 : bill.tierBoostRate\n const [, vestingTerm, , maxPayout] = terms\n const tokensRemaining = Number(\n formatUnits(\n BigInt(maxTotalPayout ?? '0') - BigInt(totalPayoutGiven),\n bill?.earnToken.decimals[bill?.chainId] ?? 18,\n ),\n )\n const treasuryBalance = customTreasuryBalance\n ? getBalanceNumber(customTreasuryBalance, bill?.earnToken?.decimals?.[bill?.chainId] ?? 18)\n : null\n\n let trueBondPrices: TrueBondPrices[] = []\n if (bill?.billVersion === BillVersion.V4) {\n trueBondPrices = trueBillPrice[0].map((data: any) => {\n return {\n points: data?.points?.toString(),\n trueBondPrice: data?.trueBondPrice.toString(),\n discount: getRawDiscount(data?.trueBondPrice.toString(), lpPrice, earnTokenPrice),\n bonus: getRawBonus(data?.trueBondPrice.toString(), lpPrice, earnTokenPrice),\n discountWithFee: getDiscountWithFee(\n feeInPayout,\n tierBoostRate,\n data?.trueBondPrice.toString(),\n lpPrice,\n earnTokenPrice,\n ),\n bonusWithFee: getBonusWithFee(\n feeInPayout,\n tierBoostRate,\n data?.trueBondPrice.toString(),\n lpPrice,\n earnTokenPrice,\n ),\n boost: TIER_MAPPING[data?.points?.toString() as keyof typeof TIER_MAPPING],\n }\n })\n } else {\n const bonus = getRawBonus(trueBillPrice, lpPrice, earnTokenPrice)\n const bonusWithFee = getBonusWithFee(feeInPayout, tierBoostRate, trueBillPrice, lpPrice, earnTokenPrice)\n const discount = getRawDiscount(trueBillPrice, lpPrice, earnTokenPrice)\n const discountWithFee = getDiscountWithFee(feeInPayout, tierBoostRate, trueBillPrice, lpPrice, earnTokenPrice)\n trueBondPrices = [\n {\n points: '0',\n boost: 0,\n trueBondPrice: trueBillPrice.toString(),\n bonus,\n bonusWithFee,\n discount,\n discountWithFee,\n },\n ]\n }\n const cleanedData: BondsData = {\n ...bill,\n soldOut: paused[0] ? true : bill.soldOut,\n feeInPayout,\n feeInPrincipal,\n showcaseTokenName: bill?.showcaseToken?.symbol ?? bill?.earnToken.symbol ?? '',\n trueBondPrices,\n principalTokenPrice: lpPrice?.toString(),\n payoutTokenPrice: earnTokenPrice?.toString(),\n tokensRemaining:\n treasuryBalance !== null\n ? Math.min(treasuryBalance, tokensRemaining).toString()\n : tokensRemaining.toString(),\n maxTotalPayout: maxTotalPayout?.toString(),\n maxPayout: maxPayout?.toString(),\n totalPayoutGiven: totalPayoutGiven?.toString(),\n vestingTerm: typeof vestingTerm === 'number' ? vestingTerm : parseInt(vestingTerm),\n tierBoostRate: bill.tierBoostRate === undefined ? 1 : bill.tierBoostRate,\n }\n return cleanedData\n }),\n )\n return [...lpStakingBondsData, ...regularBondsData]\n } catch (e) {\n console.error(e)\n reportError({\n apiUrl,\n error: e,\n extraInfo: { type: 'getBondsData', e },\n })\n return []\n }\n}\n"],"names":["BOND_2_4_0","ERC20ABI"],"mappings":"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"}
@@ -30,7 +30,13 @@ const fetchUsersBondsEVM = async (chainId, account, bondData, tokenPrices) => {
30
30
  userOwnedBills: enrichedUserBills,
31
31
  };
32
32
  });
33
- const lpStakingData = lpStakingBonds.length > 0 ? await fetchUserLpStakingBonds(chainId, account, lpStakingBonds) : [];
33
+ // Isolated, so a failed LP staking read (campaigns multicall, RPC) doesn't fail the chain's regular bills
34
+ const lpStakingData = lpStakingBonds.length > 0
35
+ ? await fetchUserLpStakingBonds(chainId, account, lpStakingBonds).catch((e) => {
36
+ console.error('Error fetching LP staking positions:', e);
37
+ return [];
38
+ })
39
+ : [];
34
40
  return Promise.resolve([...combinedData, ...lpStakingData]);
35
41
  }
36
42
  catch (error) {
@@ -210,7 +216,7 @@ const fetchUserLpStakingBonds = async (chainId, account, lpStakingBonds) => {
210
216
  billNftId: parseInt(row.token_id),
211
217
  processing: false,
212
218
  // The position NFT is a Uniswap v3 position with no bond art
213
- image: 'https://www.ape.bond/images/bills/hidden-bill.jpg',
219
+ image: 'https://www.ape.bond/images/bills/lp-staking.png',
214
220
  chainId,
215
221
  contractAddress: lpStakingConfig.positionManager,
216
222
  data: {
@@ -1 +1 @@
1
- {"version":3,"file":"fetchUsersBondsEVM.js","sources":["../../../../src/adapters/evm/state/fetchUsersBondsEVM.ts"],"sourcesContent":["import billAbi from '../../../config/abi/BOND_2_0_0.json'\nimport multicall from '../utils/multicall'\nimport { UserBill, UserOwnedBillsData } from '../../../types/yourbonds'\nimport { BillsConfig, BillVersion, ChainId } from '@ape.swap/apeswap-lists'\nimport { TokenPrices } from '../../../state/tokenPrices/useTokenPrices'\nimport { BondsData } from '../../../types/bonds'\nimport { apiGet } from '../../../utils/httpClient'\nimport { PRICE_API_URL } from '../../../config/constants/variables'\nimport partition from 'lodash-es/partition.js'\nimport APE_BOND_POSITION_ADAPTER_ABI from '../../../config/abi/apeBondPositionAdapter.json'\nexport const fetchUsersBondsEVM = async (\n chainId: ChainId,\n account: string,\n bondData: BillsConfig[],\n tokenPrices: Partial<Record<ChainId, TokenPrices[]>>,\n): Promise<UserOwnedBillsData[]> => {\n try {\n if (!account) {\n return []\n }\n const [lpStakingBonds, bonds] = partition(bondData, (bond) => bond.billType === 'lpStaking')\n\n // Fetch and set user owned bill data without NFT Data\n const userOwnedBills = await fetchUserOwnedBills(chainId, account, bonds, tokenPrices)\n const mapUserOwnedBills = bonds.map((bill: BillsConfig) =>\n userOwnedBills.filter((b) => b.address.toLowerCase() === bill.contractAddress[bill.chainId]?.toLowerCase()),\n )\n const userOwnedBillsData = bonds.map((bill: BillsConfig, i: number) => ({\n index: bill.index,\n userOwnedBills: mapUserOwnedBills[i],\n }))\n\n const combinedData = userOwnedBillsData.map((data) => {\n const enrichedUserBills = data.userOwnedBills.map((bill) => {\n return {\n ...bill,\n }\n })\n return {\n ...data,\n userOwnedBills: enrichedUserBills,\n }\n })\n\n const lpStakingData =\n lpStakingBonds.length > 0 ? await fetchUserLpStakingBonds(chainId, account, lpStakingBonds) : []\n\n return Promise.resolve([...combinedData, ...lpStakingData])\n } catch (error) {\n console.error('Error fetching user owned bills data:', error)\n return Promise.reject(error)\n }\n}\n\n// REAL's API only answers browsers from origins it allowlists, so it's called through ape.bond's proxy, which\n// forwards to REAL's API (test stack or mainnet, set on ape.bond's side).\n// TODO: staging proxy for now; switch to the production one (https://ape.bond/api/real-lp) once it's deployed.\nconst REAL_LP_API = 'https://staging.ape.bond/api/real-lp'\n// A position's page on REAL's site, where its bonus and pool rewards are claimed.\n// TODO: test site for now; REAL will send the production URL when mainnet is live.\nconst REAL_LP_DASHBOARD = 'https://staking-test.real.finance/lp/dashboard'\n\n// REAL's /rewards/<wallet>: the pool (epoch) rewards, lifetime figures. Only the fields used below are typed.\ninterface RealLpRewards {\n tokens: { token: string; symbol: string; decimals: number; claims_enabled: boolean }[]\n positions: { lineage_id: string; tokens: { token: string; claimable_wei: string }[] }[]\n}\n\n// One row of REAL's /positions/<wallet>: one episode of a position, i.e. one NFT while it sits in the vault.\n// Only the fields used below are typed.\ninterface RealLpPosition {\n token_id: string\n lineage_id: string\n next_episode_id: string | null\n stake_ordinal: number\n status: 'active' | 'rebalanced' | 'unstaked'\n tick_lower: number\n tick_upper: number\n liquidity_wei: string\n principal_usd: string\n value_usd_now: string | null\n apebond: {\n campaign_id: string\n deposited_at: number\n bonus: {\n token: string\n amount_wei: string\n unlock_at: number\n status: 'reserved' | 'claimable' | 'claimed' | 'forfeited'\n claimed_at: number | null\n token_id: string\n } | null\n } | null\n}\n\n/**\n * Raw token amounts (wei) a Uniswap v3 position holds at the pool's current tick: all token0 below its range, all\n * token1 above it, both inside. Floating point: it's for display only.\n */\nconst getPositionAmounts = (liquidity: number, tickLower: number, tickUpper: number, currentTick: number) => {\n const sqrtPrice = (tick: number) => Math.pow(1.0001, tick / 2)\n const sqrtLower = sqrtPrice(tickLower)\n const sqrtUpper = sqrtPrice(tickUpper)\n const sqrtCurrent = sqrtPrice(Math.min(Math.max(currentTick, tickLower), tickUpper))\n return {\n amount0: (liquidity * (sqrtUpper - sqrtCurrent)) / (sqrtCurrent * sqrtUpper),\n amount1: liquidity * (sqrtCurrent - sqrtLower),\n }\n}\n\n/**\n * The user's LP staking positions, shaped as purchased bonds. A position has no bill: it's a Uniswap v3 NFT staked\n * in REAL's vault, and what ApeBond pays is its bonus, reserved in REAL's escrow until the cliff. So each position\n * becomes one bill whose payout is that bonus, vesting all at once at the cliff (`vestingCliff` = `vestingTerm`).\n * Claims happen on REAL's site, so the bills are marked paused (the row's claim button would call `redeem` on the\n * vault). See docs/lp-staking-bonds/2026-10-23-real-lp-positions-rewards-api.md.\n */\nconst fetchUserLpStakingBonds = async (\n chainId: ChainId,\n account: string,\n lpStakingBonds: BillsConfig[],\n): Promise<UserOwnedBillsData[]> => {\n let rows: RealLpPosition[]\n let assetPriceUsd: string | undefined\n let assetIsToken0 = true\n let currentTick = 0\n let rewards: RealLpRewards | undefined\n try {\n const [response, rewardsResponse] = await Promise.all([\n apiGet<{\n current_tick: number\n current_price_usd: string\n asset_is_token0: boolean\n positions: RealLpPosition[]\n }>(`${REAL_LP_API}/positions/${account}`),\n // The positions still show without their pool rewards if this fails\n apiGet<RealLpRewards>(`${REAL_LP_API}/rewards/${account}`).catch((error) => {\n console.error('Error fetching LP staking rewards:', error)\n return undefined\n }),\n ])\n rewards = rewardsResponse\n rows = response?.positions ?? []\n assetPriceUsd = response?.current_price_usd\n assetIsToken0 = response?.asset_is_token0 ?? true\n currentTick = response?.current_tick ?? 0\n } catch (error) {\n // Don't fail the chain's regular bonds because REAL's API is unreachable (or refuses our origin)\n console.error('Error fetching LP staking positions:', error)\n return []\n }\n\n // All episodes of a position share its lineage_id; the one with no next episode is its current state.\n // Only positions bought through ApeBond have an apebond block.\n const currentPositions = rows.filter((row) => row.apebond && row.next_episode_id === null)\n\n // Each campaign's bonus rate and minimum bonus, for the minimum position value that earns a bonus.\n // campaigns() → (enabled, downTicks, upTicks, toleranceTicks, bonusCliffSeconds, bonusBps, minBonusAmount)\n const campaigns = await multicall(\n chainId,\n APE_BOND_POSITION_ADAPTER_ABI,\n lpStakingBonds.map((bond) => ({\n address: bond.lpStakingConfig!.adapter,\n name: 'campaigns',\n params: [bond.lpStakingConfig!.campaignId],\n })),\n )\n\n return lpStakingBonds.map((bond, bondIndex) => {\n const lpStakingConfig = bond.lpStakingConfig!\n const campaign = campaigns?.[bondIndex]\n const bonusDecimals = lpStakingConfig.bonusRewardToken.decimals[bond.chainId] ?? 18\n const bonusThreshold =\n campaign && Number(campaign[5]) > 0\n ? (Number(campaign[6]) / 10 ** bonusDecimals) * (10000 / Number(campaign[5]))\n : undefined\n const userOwnedBills: UserBill[] = currentPositions\n .filter((row) => row.apebond!.campaign_id.toLowerCase() === lpStakingConfig.campaignId.toLowerCase())\n .map((row) => {\n const { deposited_at: depositedAt, bonus } = row.apebond!\n // No bonus when the purchase was below the campaign minimum; forfeited bonuses have amount 0\n const amount = bonus?.amount_wei ?? '0'\n const cliff = bonus ? bonus.unlock_at - depositedAt : 0\n const chainId = bond.chainId\n const bonusToken = lpStakingConfig.bonusRewardToken\n // The pool is the bonus token ($ASSET) paired with the bond's principal token (USDC)\n const assetToken = {\n address: bonusToken.address[chainId] ?? '',\n symbol: bonusToken.symbol,\n name: bonusToken.symbol,\n decimals: bonusToken.decimals,\n }\n const pairedToken = {\n address: bond.lpToken.address[chainId] ?? '',\n symbol: bond.lpToken.symbol,\n name: bond.lpToken.symbol,\n decimals: bond.lpToken.decimals,\n }\n // Value of the position when it was staked: what the buyer paid, minus the zap fees and the change returned\n const principalUsd = parseFloat(row.principal_usd ?? '0')\n // Value of the position now (null once unstaked: the vault no longer holds it)\n const valueUsdNow = parseFloat(row.value_usd_now ?? '0')\n const assetPrice = parseFloat(assetPriceUsd ?? '0')\n // What the staked position holds now. An unstaked position is back in the wallet, so nothing is staked.\n // current_price_usd is $ASSET's price in USDC, and USDC is counted at $1 (as REAL's value_usd_now does).\n const { amount0, amount1 } =\n row.status === 'unstaked'\n ? { amount0: 0, amount1: 0 }\n : getPositionAmounts(parseFloat(row.liquidity_wei), row.tick_lower, row.tick_upper, currentTick)\n const [token0, token1] = assetIsToken0 ? [assetToken, pairedToken] : [pairedToken, assetToken]\n const toStakedToken = (token: typeof assetToken, rawAmount: number) => {\n const amount = rawAmount / 10 ** (token.decimals[chainId] ?? 18)\n return {\n address: token.address,\n symbol: token.symbol,\n amount,\n amountUsd: amount * (token === assetToken ? assetPrice : 1),\n }\n }\n return {\n // Rows are matched to their bond by contract address; for LP staking that's the vault\n address: bond.contractAddress[bond.chainId] ?? '',\n // The position's current NFT, the one REAL's page link uses. After a rebalance past the cliff the escrow\n // still pays on the NFT id the position had at the cliff (bonus.token_id), which has no field here.\n id: row.token_id,\n // The NFT contract is the position manager. The price range (price_lower_usd / price_upper_usd,\n // range_status_now) has no field.\n // Neither do the position's status (an unstaked position still shows, with its bonus as the API reports\n // it) and `finalized` (false for ~13 min after a purchase).\n billNftAddress: lpStakingConfig.positionManager,\n totalPayout: amount,\n // What's left to receive: everything until it's claimed (or forfeited, where amount is 0)\n payout: bonus?.status === 'claimed' ? '0' : amount,\n pendingRewards: bonus?.status === 'claimable' ? amount : '0',\n payoutClaimed: bonus?.status === 'claimed' ? amount : '0',\n vestingStartTimestamp: depositedAt.toString(),\n vestingTerm: cliff.toString(),\n lastBlockTimestamp: (bonus?.claimed_at ?? depositedAt).toString(),\n // No price per payout token: the bonus is a share of the position's value\n truePricePaid: '0',\n paused: true,\n lpStakingData: {\n token0: toStakedToken(token0, amount0),\n token1: toStakedToken(token1, amount1),\n bonusStatus: bonus?.status ?? null,\n bonusThreshold,\n // The position's page on REAL's site. The ordinal is only appended from 2 on (an NFT staked again by\n // hand after an unstake); older ids of the lineage redirect to the current one.\n positionUrl: `${REAL_LP_DASHBOARD}/${row.token_id}${row.stake_ordinal >= 2 ? `-${row.stake_ordinal}` : ''}`,\n // Matched by lineage_id, shared by every episode of the position (it survives rebalances)\n poolRewards: rewards\n ? rewards.tokens.map((rewardToken) => {\n const positionToken = rewards!.positions\n .find((position) => position.lineage_id === row.lineage_id)\n ?.tokens.find((token) => token.token.toLowerCase() === rewardToken.token.toLowerCase())\n // claimable_wei is what's earned and not claimed yet; $ASSET can't be claimed before\n // claims_enabled (mainnet launch + REAL's timelock)\n const rewardAmount = Number(positionToken?.claimable_wei ?? '0') / 10 ** rewardToken.decimals\n return {\n address: rewardToken.token,\n symbol: rewardToken.symbol,\n amount: rewardAmount,\n // Only $ASSET has a price (current_price_usd); REAL's API doesn't price $OVTR\n amountUsd:\n rewardToken.token.toLowerCase() === assetToken.address.toLowerCase()\n ? rewardAmount * assetPrice\n : undefined,\n claimsEnabled: rewardToken.claims_enabled,\n }\n })\n : undefined,\n },\n // What api-v2 provides for regular bills, here from REAL's API (useUserBonds doesn't send LP staking\n // bills to api-v2)\n nftData: {\n tokenId: parseInt(row.token_id),\n billNftId: parseInt(row.token_id),\n processing: false,\n // The position NFT is a Uniswap v3 position with no bond art\n image: 'https://www.ape.bond/images/bills/hidden-bill.jpg',\n chainId,\n contractAddress: lpStakingConfig.positionManager,\n data: {\n billContract: bond.contractAddress[chainId] ?? '',\n billNftAddress: lpStakingConfig.positionManager,\n billNftId: parseInt(row.token_id),\n // Not in REAL's API\n blockNumber: 0,\n bondArtCollection: '',\n bondPartner: bond.bondPartner ?? '',\n bondVersion: bond.billVersion ?? '',\n chainId,\n // The purchase opened the position's first episode, whose id is <token_id>-<opening tx hash>\n createTransactionHash: row.lineage_id.split('-')[1] ?? '',\n createdAddressOwner: account,\n createdAt: depositedAt,\n // The amount paid isn't in REAL's API (only in the purchase tx). The principal token is USDC, so the\n // position's USD value at purchase stands in for it.\n deposit: principalUsd,\n dollarValue: principalUsd,\n expires: depositedAt + cliff,\n pairName: assetIsToken0\n ? `${assetToken.symbol}-${pairedToken.symbol}`\n : `${pairedToken.symbol}-${assetToken.symbol}`,\n // The position's current value (used by the share image), in $ASSET (the payout token) so that\n // payout × payoutTokenPrice gives value_usd_now back. The bonus itself is in the bill's payout fields.\n payout: assetPrice > 0 ? valueUsdNow / assetPrice : 0,\n payoutToken: assetToken.address,\n payoutTokenData: {\n address: assetToken.address,\n name: assetToken.name,\n symbol: assetToken.symbol,\n decimals: assetToken.decimals,\n },\n payoutTokenPrice: assetPriceUsd ?? '0',\n principalToken: pairedToken.address,\n token0: assetIsToken0 ? assetToken : pairedToken,\n token1: assetIsToken0 ? pairedToken : assetToken,\n type: bond.billType,\n vestingPeriodSeconds: cliff,\n },\n },\n // The bonus is paid in the bonus token, not the bond's earnToken, and only unlocks at the cliff.\n // The $OVTR and $ASSET staking rewards (REAL's /rewards/<wallet>) have no field.\n bond: {\n ...bond,\n earnToken: lpStakingConfig.bonusRewardToken,\n vestingCliff: cliff,\n vestingTerm: cliff,\n payoutTokenPrice: assetPriceUsd,\n } as BondsData,\n }\n })\n return { index: bond.index, userOwnedBills }\n })\n}\n\nconst fetchUserOwnedBills = async (\n chainId: ChainId,\n account: string,\n bonds: BillsConfig[],\n tokenPrices: Partial<Record<ChainId, TokenPrices[]>>,\n): Promise<UserBill[]> => {\n // Maps all the bills in the list repo to make a call to each of them to get Bills Id and paused state (only for V4)\n const billIdAndPausedCalls = bonds.flatMap((b, index) => {\n const calls = [\n {\n address: b.contractAddress[b.chainId] ?? '',\n name: 'getBillIds',\n params: [account],\n bondIndex: index,\n },\n ]\n // Only add paused call for V4 bonds\n if (b.billVersion === BillVersion.V4) {\n calls.push({\n address: b.contractAddress[b.chainId] ?? '',\n name: 'paused',\n params: [],\n bondIndex: index,\n })\n }\n return calls\n })\n const billIdAndPausedResults = await multicall(chainId, billAbi, billIdAndPausedCalls, true, 15)\n\n // Separate billIds and pausedStates from results, tracking which bonds have paused calls\n const billIds: any[] = []\n const pausedStates: Map<string, boolean> = new Map()\n let resultIndex = 0\n\n bonds.forEach((b) => {\n // First result is always getBillIds\n billIds.push(billIdAndPausedResults?.[resultIndex])\n resultIndex++\n\n // Next result is paused only if V4\n if (b.billVersion === BillVersion.V4) {\n pausedStates.set(\n b.contractAddress[b.chainId]?.toLowerCase() as string,\n billIdAndPausedResults?.[resultIndex]?.[0] ?? false,\n )\n resultIndex++\n }\n })\n const billDataCalls: any = []\n const billVersions: any = []\n\n billIds?.forEach((idArray: any, index: number) =>\n idArray[0].forEach((id: bigint) => {\n if (id > 0) {\n billDataCalls.push({\n address: bonds[index].contractAddress[bonds[index].chainId],\n name: bonds[index].billVersion !== BillVersion.V1 ? 'getBillInfo' : 'billInfo',\n params: [id],\n bond: bonds[index],\n })\n billDataCalls.push({\n address: bonds[index].contractAddress[bonds[index].chainId],\n name: bonds[index].billVersion !== BillVersion.V1 ? 'claimablePayout' : 'pendingPayoutFor',\n params: [id],\n bond: bonds[index],\n })\n billVersions.push(bonds[index].billVersion)\n }\n }),\n )\n const billData = await multicall(chainId, billAbi, billDataCalls, true, 150)\n const result = []\n\n for (let i = 0; i < billVersions.length; i++) {\n const billPos = i === 0 ? 0 : i * 2\n let bond: BondsData = billDataCalls[billPos].bond\n\n let principalTokenPrice = tokenPrices?.[bond.chainId]?.find(\n (tokenPrice) => tokenPrice.tokenAddress?.toLowerCase() === bond?.lpToken?.address?.[bond.chainId]?.toLowerCase(),\n )?.price\n\n let payoutTokenPrice = tokenPrices?.[bond.chainId]?.find(\n (tokenPrice: TokenPrices) =>\n tokenPrice?.tokenAddress?.toLowerCase() === bond?.earnToken?.address?.[bond.chainId]?.toLowerCase(),\n )?.price\n\n if (principalTokenPrice === undefined) {\n try {\n const res = await apiGet<{ price: string }>(\n `${PRICE_API_URL}/realtime/price?token=${bond?.lpToken?.address?.[bond?.chainId]}&chain=${bond?.chainId}`,\n )\n console.log('Individual call for: ', bond.lpToken.symbol, '. Price: ', res.price)\n principalTokenPrice = parseFloat(res.price ?? '0')\n } catch {\n principalTokenPrice = 0\n }\n }\n if (payoutTokenPrice === undefined) {\n try {\n const res = await apiGet<{ price: string }>(\n `${PRICE_API_URL}/realtime/price?token=${bond?.earnToken?.address?.[bond?.chainId]}&chain=${bond?.chainId}`,\n )\n console.log('Individual call for: ', bond.earnToken.symbol, '. Price: ', res.price)\n payoutTokenPrice = parseFloat(res.price ?? '0')\n } catch {\n payoutTokenPrice = 0\n }\n }\n\n bond = {\n ...bond,\n payoutTokenPrice: payoutTokenPrice?.toString(),\n principalTokenPrice: principalTokenPrice?.toString(),\n }\n const paused = pausedStates.get(bond.contractAddress[bond.chainId]?.toLowerCase() as string) ?? false\n\n const data =\n billVersions[i] !== BillVersion.V1\n ? {\n address: billDataCalls[billPos].address,\n id: billDataCalls[billPos].params[0].toString(),\n payout: (\n BigInt(billData[billPos][0]?.payout.toString()) - BigInt(billData[billPos][0]?.payoutClaimed.toString())\n ).toString(),\n totalPayout: billData[billPos][0]?.payout.toString(),\n payoutClaimed: billData[billPos][0]?.payoutClaimed.toString(),\n billNftAddress: bond.billNnftAddress[bond.chainId] ?? '',\n vesting: billData[billPos][0]?.vesting.toString(),\n vestingTerm: billData[billPos][0]?.vestingTerm.toString(),\n lastBlockTimestamp: billData[billPos][0]?.lastClaimTimestamp.toString(),\n vestingStartTimestamp: billData[billPos][0]?.vestingStartTimestamp.toString(),\n truePricePaid: billData[billPos][0]?.truePricePaid.toString(),\n pendingRewards: billData[billPos + 1][0].toString(),\n paused,\n bond,\n }\n : {\n address: billDataCalls[billPos].address,\n id: billDataCalls[billPos].params[0].toString(),\n payoutClaimed: billData?.[billPos]?.[0]?.payoutClaimed?.toString(),\n payout: billData[billPos][0].toString(),\n billNftAddress: bond.billNnftAddress[bond.chainId] ?? '',\n vesting: billData[billPos][1].toString(),\n lastBlockTimestamp: billData[billPos][2].toString(),\n truePricePaid: billData[billPos][3].toString(),\n pendingRewards: billData[billPos + 1][0].toString(),\n paused,\n bond,\n }\n result.push(data)\n }\n\n return result\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetchUsersBondsEVM.js","sources":["../../../../src/adapters/evm/state/fetchUsersBondsEVM.ts"],"sourcesContent":["import billAbi from '../../../config/abi/BOND_2_0_0.json'\nimport multicall from '../utils/multicall'\nimport { UserBill, UserOwnedBillsData } from '../../../types/yourbonds'\nimport { BillsConfig, BillVersion, ChainId } from '@ape.swap/apeswap-lists'\nimport { TokenPrices } from '../../../state/tokenPrices/useTokenPrices'\nimport { BondsData } from '../../../types/bonds'\nimport { apiGet } from '../../../utils/httpClient'\nimport { PRICE_API_URL } from '../../../config/constants/variables'\nimport partition from 'lodash-es/partition.js'\nimport APE_BOND_POSITION_ADAPTER_ABI from '../../../config/abi/apeBondPositionAdapter.json'\nexport const fetchUsersBondsEVM = async (\n chainId: ChainId,\n account: string,\n bondData: BillsConfig[],\n tokenPrices: Partial<Record<ChainId, TokenPrices[]>>,\n): Promise<UserOwnedBillsData[]> => {\n try {\n if (!account) {\n return []\n }\n const [lpStakingBonds, bonds] = partition(bondData, (bond) => bond.billType === 'lpStaking')\n\n // Fetch and set user owned bill data without NFT Data\n const userOwnedBills = await fetchUserOwnedBills(chainId, account, bonds, tokenPrices)\n const mapUserOwnedBills = bonds.map((bill: BillsConfig) =>\n userOwnedBills.filter((b) => b.address.toLowerCase() === bill.contractAddress[bill.chainId]?.toLowerCase()),\n )\n const userOwnedBillsData = bonds.map((bill: BillsConfig, i: number) => ({\n index: bill.index,\n userOwnedBills: mapUserOwnedBills[i],\n }))\n\n const combinedData = userOwnedBillsData.map((data) => {\n const enrichedUserBills = data.userOwnedBills.map((bill) => {\n return {\n ...bill,\n }\n })\n return {\n ...data,\n userOwnedBills: enrichedUserBills,\n }\n })\n\n // Isolated, so a failed LP staking read (campaigns multicall, RPC) doesn't fail the chain's regular bills\n const lpStakingData =\n lpStakingBonds.length > 0\n ? await fetchUserLpStakingBonds(chainId, account, lpStakingBonds).catch((e) => {\n console.error('Error fetching LP staking positions:', e)\n return []\n })\n : []\n\n return Promise.resolve([...combinedData, ...lpStakingData])\n } catch (error) {\n console.error('Error fetching user owned bills data:', error)\n return Promise.reject(error)\n }\n}\n\n// REAL's API only answers browsers from origins it allowlists, so it's called through ape.bond's proxy, which\n// forwards to REAL's API (test stack or mainnet, set on ape.bond's side).\n// TODO: staging proxy for now; switch to the production one (https://ape.bond/api/real-lp) once it's deployed.\nconst REAL_LP_API = 'https://staging.ape.bond/api/real-lp'\n// A position's page on REAL's site, where its bonus and pool rewards are claimed.\n// TODO: test site for now; REAL will send the production URL when mainnet is live.\nconst REAL_LP_DASHBOARD = 'https://staking-test.real.finance/lp/dashboard'\n\n// REAL's /rewards/<wallet>: the pool (epoch) rewards, lifetime figures. Only the fields used below are typed.\ninterface RealLpRewards {\n tokens: { token: string; symbol: string; decimals: number; claims_enabled: boolean }[]\n positions: { lineage_id: string; tokens: { token: string; claimable_wei: string }[] }[]\n}\n\n// One row of REAL's /positions/<wallet>: one episode of a position, i.e. one NFT while it sits in the vault.\n// Only the fields used below are typed.\ninterface RealLpPosition {\n token_id: string\n lineage_id: string\n next_episode_id: string | null\n stake_ordinal: number\n status: 'active' | 'rebalanced' | 'unstaked'\n tick_lower: number\n tick_upper: number\n liquidity_wei: string\n principal_usd: string\n value_usd_now: string | null\n apebond: {\n campaign_id: string\n deposited_at: number\n bonus: {\n token: string\n amount_wei: string\n unlock_at: number\n status: 'reserved' | 'claimable' | 'claimed' | 'forfeited'\n claimed_at: number | null\n token_id: string\n } | null\n } | null\n}\n\n/**\n * Raw token amounts (wei) a Uniswap v3 position holds at the pool's current tick: all token0 below its range, all\n * token1 above it, both inside. Floating point: it's for display only.\n */\nconst getPositionAmounts = (liquidity: number, tickLower: number, tickUpper: number, currentTick: number) => {\n const sqrtPrice = (tick: number) => Math.pow(1.0001, tick / 2)\n const sqrtLower = sqrtPrice(tickLower)\n const sqrtUpper = sqrtPrice(tickUpper)\n const sqrtCurrent = sqrtPrice(Math.min(Math.max(currentTick, tickLower), tickUpper))\n return {\n amount0: (liquidity * (sqrtUpper - sqrtCurrent)) / (sqrtCurrent * sqrtUpper),\n amount1: liquidity * (sqrtCurrent - sqrtLower),\n }\n}\n\n/**\n * The user's LP staking positions, shaped as purchased bonds. A position has no bill: it's a Uniswap v3 NFT staked\n * in REAL's vault, and what ApeBond pays is its bonus, reserved in REAL's escrow until the cliff. So each position\n * becomes one bill whose payout is that bonus, vesting all at once at the cliff (`vestingCliff` = `vestingTerm`).\n * Claims happen on REAL's site, so the bills are marked paused (the row's claim button would call `redeem` on the\n * vault). See docs/lp-staking-bonds/2026-10-23-real-lp-positions-rewards-api.md.\n */\nconst fetchUserLpStakingBonds = async (\n chainId: ChainId,\n account: string,\n lpStakingBonds: BillsConfig[],\n): Promise<UserOwnedBillsData[]> => {\n let rows: RealLpPosition[]\n let assetPriceUsd: string | undefined\n let assetIsToken0 = true\n let currentTick = 0\n let rewards: RealLpRewards | undefined\n try {\n const [response, rewardsResponse] = await Promise.all([\n apiGet<{\n current_tick: number\n current_price_usd: string\n asset_is_token0: boolean\n positions: RealLpPosition[]\n }>(`${REAL_LP_API}/positions/${account}`),\n // The positions still show without their pool rewards if this fails\n apiGet<RealLpRewards>(`${REAL_LP_API}/rewards/${account}`).catch((error) => {\n console.error('Error fetching LP staking rewards:', error)\n return undefined\n }),\n ])\n rewards = rewardsResponse\n rows = response?.positions ?? []\n assetPriceUsd = response?.current_price_usd\n assetIsToken0 = response?.asset_is_token0 ?? true\n currentTick = response?.current_tick ?? 0\n } catch (error) {\n // Don't fail the chain's regular bonds because REAL's API is unreachable (or refuses our origin)\n console.error('Error fetching LP staking positions:', error)\n return []\n }\n\n // All episodes of a position share its lineage_id; the one with no next episode is its current state.\n // Only positions bought through ApeBond have an apebond block.\n const currentPositions = rows.filter((row) => row.apebond && row.next_episode_id === null)\n\n // Each campaign's bonus rate and minimum bonus, for the minimum position value that earns a bonus.\n // campaigns() → (enabled, downTicks, upTicks, toleranceTicks, bonusCliffSeconds, bonusBps, minBonusAmount)\n const campaigns = await multicall(\n chainId,\n APE_BOND_POSITION_ADAPTER_ABI,\n lpStakingBonds.map((bond) => ({\n address: bond.lpStakingConfig!.adapter,\n name: 'campaigns',\n params: [bond.lpStakingConfig!.campaignId],\n })),\n )\n\n return lpStakingBonds.map((bond, bondIndex) => {\n const lpStakingConfig = bond.lpStakingConfig!\n const campaign = campaigns?.[bondIndex]\n const bonusDecimals = lpStakingConfig.bonusRewardToken.decimals[bond.chainId] ?? 18\n const bonusThreshold =\n campaign && Number(campaign[5]) > 0\n ? (Number(campaign[6]) / 10 ** bonusDecimals) * (10000 / Number(campaign[5]))\n : undefined\n const userOwnedBills: UserBill[] = currentPositions\n .filter((row) => row.apebond!.campaign_id.toLowerCase() === lpStakingConfig.campaignId.toLowerCase())\n .map((row) => {\n const { deposited_at: depositedAt, bonus } = row.apebond!\n // No bonus when the purchase was below the campaign minimum; forfeited bonuses have amount 0\n const amount = bonus?.amount_wei ?? '0'\n const cliff = bonus ? bonus.unlock_at - depositedAt : 0\n const chainId = bond.chainId\n const bonusToken = lpStakingConfig.bonusRewardToken\n // The pool is the bonus token ($ASSET) paired with the bond's principal token (USDC)\n const assetToken = {\n address: bonusToken.address[chainId] ?? '',\n symbol: bonusToken.symbol,\n name: bonusToken.symbol,\n decimals: bonusToken.decimals,\n }\n const pairedToken = {\n address: bond.lpToken.address[chainId] ?? '',\n symbol: bond.lpToken.symbol,\n name: bond.lpToken.symbol,\n decimals: bond.lpToken.decimals,\n }\n // Value of the position when it was staked: what the buyer paid, minus the zap fees and the change returned\n const principalUsd = parseFloat(row.principal_usd ?? '0')\n // Value of the position now (null once unstaked: the vault no longer holds it)\n const valueUsdNow = parseFloat(row.value_usd_now ?? '0')\n const assetPrice = parseFloat(assetPriceUsd ?? '0')\n // What the staked position holds now. An unstaked position is back in the wallet, so nothing is staked.\n // current_price_usd is $ASSET's price in USDC, and USDC is counted at $1 (as REAL's value_usd_now does).\n const { amount0, amount1 } =\n row.status === 'unstaked'\n ? { amount0: 0, amount1: 0 }\n : getPositionAmounts(parseFloat(row.liquidity_wei), row.tick_lower, row.tick_upper, currentTick)\n const [token0, token1] = assetIsToken0 ? [assetToken, pairedToken] : [pairedToken, assetToken]\n const toStakedToken = (token: typeof assetToken, rawAmount: number) => {\n const amount = rawAmount / 10 ** (token.decimals[chainId] ?? 18)\n return {\n address: token.address,\n symbol: token.symbol,\n amount,\n amountUsd: amount * (token === assetToken ? assetPrice : 1),\n }\n }\n return {\n // Rows are matched to their bond by contract address; for LP staking that's the vault\n address: bond.contractAddress[bond.chainId] ?? '',\n // The position's current NFT, the one REAL's page link uses. After a rebalance past the cliff the escrow\n // still pays on the NFT id the position had at the cliff (bonus.token_id), which has no field here.\n id: row.token_id,\n // The NFT contract is the position manager. The price range (price_lower_usd / price_upper_usd,\n // range_status_now) has no field.\n // Neither do the position's status (an unstaked position still shows, with its bonus as the API reports\n // it) and `finalized` (false for ~13 min after a purchase).\n billNftAddress: lpStakingConfig.positionManager,\n totalPayout: amount,\n // What's left to receive: everything until it's claimed (or forfeited, where amount is 0)\n payout: bonus?.status === 'claimed' ? '0' : amount,\n pendingRewards: bonus?.status === 'claimable' ? amount : '0',\n payoutClaimed: bonus?.status === 'claimed' ? amount : '0',\n vestingStartTimestamp: depositedAt.toString(),\n vestingTerm: cliff.toString(),\n lastBlockTimestamp: (bonus?.claimed_at ?? depositedAt).toString(),\n // No price per payout token: the bonus is a share of the position's value\n truePricePaid: '0',\n paused: true,\n lpStakingData: {\n token0: toStakedToken(token0, amount0),\n token1: toStakedToken(token1, amount1),\n bonusStatus: bonus?.status ?? null,\n bonusThreshold,\n // The position's page on REAL's site. The ordinal is only appended from 2 on (an NFT staked again by\n // hand after an unstake); older ids of the lineage redirect to the current one.\n positionUrl: `${REAL_LP_DASHBOARD}/${row.token_id}${row.stake_ordinal >= 2 ? `-${row.stake_ordinal}` : ''}`,\n // Matched by lineage_id, shared by every episode of the position (it survives rebalances)\n poolRewards: rewards\n ? rewards.tokens.map((rewardToken) => {\n const positionToken = rewards!.positions\n .find((position) => position.lineage_id === row.lineage_id)\n ?.tokens.find((token) => token.token.toLowerCase() === rewardToken.token.toLowerCase())\n // claimable_wei is what's earned and not claimed yet; $ASSET can't be claimed before\n // claims_enabled (mainnet launch + REAL's timelock)\n const rewardAmount = Number(positionToken?.claimable_wei ?? '0') / 10 ** rewardToken.decimals\n return {\n address: rewardToken.token,\n symbol: rewardToken.symbol,\n amount: rewardAmount,\n // Only $ASSET has a price (current_price_usd); REAL's API doesn't price $OVTR\n amountUsd:\n rewardToken.token.toLowerCase() === assetToken.address.toLowerCase()\n ? rewardAmount * assetPrice\n : undefined,\n claimsEnabled: rewardToken.claims_enabled,\n }\n })\n : undefined,\n },\n // What api-v2 provides for regular bills, here from REAL's API (useUserBonds doesn't send LP staking\n // bills to api-v2)\n nftData: {\n tokenId: parseInt(row.token_id),\n billNftId: parseInt(row.token_id),\n processing: false,\n // The position NFT is a Uniswap v3 position with no bond art\n image: 'https://www.ape.bond/images/bills/lp-staking.png',\n chainId,\n contractAddress: lpStakingConfig.positionManager,\n data: {\n billContract: bond.contractAddress[chainId] ?? '',\n billNftAddress: lpStakingConfig.positionManager,\n billNftId: parseInt(row.token_id),\n // Not in REAL's API\n blockNumber: 0,\n bondArtCollection: '',\n bondPartner: bond.bondPartner ?? '',\n bondVersion: bond.billVersion ?? '',\n chainId,\n // The purchase opened the position's first episode, whose id is <token_id>-<opening tx hash>\n createTransactionHash: row.lineage_id.split('-')[1] ?? '',\n createdAddressOwner: account,\n createdAt: depositedAt,\n // The amount paid isn't in REAL's API (only in the purchase tx). The principal token is USDC, so the\n // position's USD value at purchase stands in for it.\n deposit: principalUsd,\n dollarValue: principalUsd,\n expires: depositedAt + cliff,\n pairName: assetIsToken0\n ? `${assetToken.symbol}-${pairedToken.symbol}`\n : `${pairedToken.symbol}-${assetToken.symbol}`,\n // The position's current value (used by the share image), in $ASSET (the payout token) so that\n // payout × payoutTokenPrice gives value_usd_now back. The bonus itself is in the bill's payout fields.\n payout: assetPrice > 0 ? valueUsdNow / assetPrice : 0,\n payoutToken: assetToken.address,\n payoutTokenData: {\n address: assetToken.address,\n name: assetToken.name,\n symbol: assetToken.symbol,\n decimals: assetToken.decimals,\n },\n payoutTokenPrice: assetPriceUsd ?? '0',\n principalToken: pairedToken.address,\n token0: assetIsToken0 ? assetToken : pairedToken,\n token1: assetIsToken0 ? pairedToken : assetToken,\n type: bond.billType,\n vestingPeriodSeconds: cliff,\n },\n },\n // The bonus is paid in the bonus token, not the bond's earnToken, and only unlocks at the cliff.\n // The $OVTR and $ASSET staking rewards (REAL's /rewards/<wallet>) have no field.\n bond: {\n ...bond,\n earnToken: lpStakingConfig.bonusRewardToken,\n vestingCliff: cliff,\n vestingTerm: cliff,\n payoutTokenPrice: assetPriceUsd,\n } as BondsData,\n }\n })\n return { index: bond.index, userOwnedBills }\n })\n}\n\nconst fetchUserOwnedBills = async (\n chainId: ChainId,\n account: string,\n bonds: BillsConfig[],\n tokenPrices: Partial<Record<ChainId, TokenPrices[]>>,\n): Promise<UserBill[]> => {\n // Maps all the bills in the list repo to make a call to each of them to get Bills Id and paused state (only for V4)\n const billIdAndPausedCalls = bonds.flatMap((b, index) => {\n const calls = [\n {\n address: b.contractAddress[b.chainId] ?? '',\n name: 'getBillIds',\n params: [account],\n bondIndex: index,\n },\n ]\n // Only add paused call for V4 bonds\n if (b.billVersion === BillVersion.V4) {\n calls.push({\n address: b.contractAddress[b.chainId] ?? '',\n name: 'paused',\n params: [],\n bondIndex: index,\n })\n }\n return calls\n })\n const billIdAndPausedResults = await multicall(chainId, billAbi, billIdAndPausedCalls, true, 15)\n\n // Separate billIds and pausedStates from results, tracking which bonds have paused calls\n const billIds: any[] = []\n const pausedStates: Map<string, boolean> = new Map()\n let resultIndex = 0\n\n bonds.forEach((b) => {\n // First result is always getBillIds\n billIds.push(billIdAndPausedResults?.[resultIndex])\n resultIndex++\n\n // Next result is paused only if V4\n if (b.billVersion === BillVersion.V4) {\n pausedStates.set(\n b.contractAddress[b.chainId]?.toLowerCase() as string,\n billIdAndPausedResults?.[resultIndex]?.[0] ?? false,\n )\n resultIndex++\n }\n })\n const billDataCalls: any = []\n const billVersions: any = []\n\n billIds?.forEach((idArray: any, index: number) =>\n idArray[0].forEach((id: bigint) => {\n if (id > 0) {\n billDataCalls.push({\n address: bonds[index].contractAddress[bonds[index].chainId],\n name: bonds[index].billVersion !== BillVersion.V1 ? 'getBillInfo' : 'billInfo',\n params: [id],\n bond: bonds[index],\n })\n billDataCalls.push({\n address: bonds[index].contractAddress[bonds[index].chainId],\n name: bonds[index].billVersion !== BillVersion.V1 ? 'claimablePayout' : 'pendingPayoutFor',\n params: [id],\n bond: bonds[index],\n })\n billVersions.push(bonds[index].billVersion)\n }\n }),\n )\n const billData = await multicall(chainId, billAbi, billDataCalls, true, 150)\n const result = []\n\n for (let i = 0; i < billVersions.length; i++) {\n const billPos = i === 0 ? 0 : i * 2\n let bond: BondsData = billDataCalls[billPos].bond\n\n let principalTokenPrice = tokenPrices?.[bond.chainId]?.find(\n (tokenPrice) => tokenPrice.tokenAddress?.toLowerCase() === bond?.lpToken?.address?.[bond.chainId]?.toLowerCase(),\n )?.price\n\n let payoutTokenPrice = tokenPrices?.[bond.chainId]?.find(\n (tokenPrice: TokenPrices) =>\n tokenPrice?.tokenAddress?.toLowerCase() === bond?.earnToken?.address?.[bond.chainId]?.toLowerCase(),\n )?.price\n\n if (principalTokenPrice === undefined) {\n try {\n const res = await apiGet<{ price: string }>(\n `${PRICE_API_URL}/realtime/price?token=${bond?.lpToken?.address?.[bond?.chainId]}&chain=${bond?.chainId}`,\n )\n console.log('Individual call for: ', bond.lpToken.symbol, '. Price: ', res.price)\n principalTokenPrice = parseFloat(res.price ?? '0')\n } catch {\n principalTokenPrice = 0\n }\n }\n if (payoutTokenPrice === undefined) {\n try {\n const res = await apiGet<{ price: string }>(\n `${PRICE_API_URL}/realtime/price?token=${bond?.earnToken?.address?.[bond?.chainId]}&chain=${bond?.chainId}`,\n )\n console.log('Individual call for: ', bond.earnToken.symbol, '. Price: ', res.price)\n payoutTokenPrice = parseFloat(res.price ?? '0')\n } catch {\n payoutTokenPrice = 0\n }\n }\n\n bond = {\n ...bond,\n payoutTokenPrice: payoutTokenPrice?.toString(),\n principalTokenPrice: principalTokenPrice?.toString(),\n }\n const paused = pausedStates.get(bond.contractAddress[bond.chainId]?.toLowerCase() as string) ?? false\n\n const data =\n billVersions[i] !== BillVersion.V1\n ? {\n address: billDataCalls[billPos].address,\n id: billDataCalls[billPos].params[0].toString(),\n payout: (\n BigInt(billData[billPos][0]?.payout.toString()) - BigInt(billData[billPos][0]?.payoutClaimed.toString())\n ).toString(),\n totalPayout: billData[billPos][0]?.payout.toString(),\n payoutClaimed: billData[billPos][0]?.payoutClaimed.toString(),\n billNftAddress: bond.billNnftAddress[bond.chainId] ?? '',\n vesting: billData[billPos][0]?.vesting.toString(),\n vestingTerm: billData[billPos][0]?.vestingTerm.toString(),\n lastBlockTimestamp: billData[billPos][0]?.lastClaimTimestamp.toString(),\n vestingStartTimestamp: billData[billPos][0]?.vestingStartTimestamp.toString(),\n truePricePaid: billData[billPos][0]?.truePricePaid.toString(),\n pendingRewards: billData[billPos + 1][0].toString(),\n paused,\n bond,\n }\n : {\n address: billDataCalls[billPos].address,\n id: billDataCalls[billPos].params[0].toString(),\n payoutClaimed: billData?.[billPos]?.[0]?.payoutClaimed?.toString(),\n payout: billData[billPos][0].toString(),\n billNftAddress: bond.billNnftAddress[bond.chainId] ?? '',\n vesting: billData[billPos][1].toString(),\n lastBlockTimestamp: billData[billPos][2].toString(),\n truePricePaid: billData[billPos][3].toString(),\n pendingRewards: billData[billPos + 1][0].toString(),\n paused,\n bond,\n }\n result.push(data)\n }\n\n return result\n}\n"],"names":[],"mappings":"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"}
@@ -57,13 +57,17 @@ const useSoulZapLpStakingQuote = (typedValue, inputCurrency, bond, account) => {
57
57
  if (!zapInputData)
58
58
  return null;
59
59
  return [
60
- 'zapBondDetails',
60
+ 'zapLpStakingDetails',
61
61
  zapInputData.chain,
62
62
  zapInputData.user,
63
63
  zapInputData.lpData.lpType,
64
64
  zapInputData.lpData.fromToken,
65
65
  zapInputData.lpData.fromAmount,
66
66
  zapInputData.lpData.slippage,
67
+ zapInputData.lpData.pool,
68
+ zapInputData.lpData.positionManager,
69
+ zapInputData.protocolData.adapter,
70
+ zapInputData.protocolData.campaignId,
67
71
  ];
68
72
  }, [zapInputData]);
69
73
  const fetchZapDetails = async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"useSoulZapLpStakingQuote.js","sources":["../../../../../src/adapters/evm/state/lpStaking/useSoulZapLpStakingQuote.ts"],"sourcesContent":["import { useMemo } from 'react'\nimport { ChainId, Token } from '@ape.swap/apeswap-lists'\nimport { getChainParam } from '../../../../state/zap/getChainParam'\nimport { apiPost } from '../../../../utils/httpClient'\nimport { useQuery } from '@tanstack/react-query'\nimport { QUERY_KEYS } from '../../../../config/constants/queryKeys'\nimport useCurrencyPrice from '../../../../state/price/useCurrencyPrice'\nimport { BondsData } from '../../../../types/bonds'\nimport { useSlippage } from '../../../../state/slippage/useSlippage'\nimport useDebounce from '../../../../hooks/useDebounce'\nimport { WNATIVE, zapInputTokens } from '@ape.swap/apeswap-lists'\nimport { SOUL_ZAP_API } from '../../../../config/constants/variables'\nimport { formatUnits, parseUnits } from '../../../../utils/fixedPoint'\nimport multicall from '../../utils/multicall'\nimport APE_BOND_POSITION_ADAPTER_ABI from '../../../../config/abi/apeBondPositionAdapter.json'\n\nconst useSoulZapLpStakingQuote = (\n typedValue: string,\n inputCurrency: 'NATIVE' | Token | undefined,\n bond: BondsData | undefined,\n account?: string,\n): [loading: boolean, response: any, depositAmount: string, error: boolean, trueBondPrice: string | undefined] => {\n const debouncedInput = useDebounce(typedValue, 500)\n const isDebouncing = typedValue !== debouncedInput\n const { evmSlippage: slippage } = useSlippage()\n\n const principalToken = bond?.lpToken as Token\n const chainId = bond?.chainId as ChainId\n const inputCurrencyString =\n inputCurrency === 'NATIVE' ? '0x0000000000000000000000000000000000000000' : inputCurrency?.address[chainId]\n const inputCurrencyDecimals = inputCurrency === 'NATIVE' ? 18 : inputCurrency?.decimals![chainId]\n const chainName = getChainParam(chainId)\n\n const bigishInputAmount = parseUnits(debouncedInput ?? '0', inputCurrencyDecimals ?? 18).toString()\n const lpStakingConfig = bond?.lpStakingConfig\n\n const zapInputData = useMemo(() => {\n if (\n chainName &&\n inputCurrencyString &&\n inputCurrencyDecimals &&\n bigishInputAmount !== 'NaN' &&\n bigishInputAmount !== '0' &&\n lpStakingConfig\n ) {\n return {\n chain: chainName,\n recipient: account ?? '0x0000000000000000000000000000000000000000',\n user: account ?? '0x0000000000000000000000000000000000000000',\n integrator: 'apebond',\n lpData: {\n fromToken: inputCurrencyString,\n fromAmount: bigishInputAmount,\n lpType: lpStakingConfig.lpType,\n positionManager: lpStakingConfig.positionManager,\n pool: lpStakingConfig.pool,\n slippage,\n tickLower: '0', //TODO add this\n tickUpper: '0', //TODO add this\n },\n protocolData: {\n protocol: 'RealFinance',\n adapter: lpStakingConfig.adapter,\n campaignId: lpStakingConfig.campaignId,\n },\n }\n }\n }, [account, bigishInputAmount, chainName, inputCurrencyDecimals, inputCurrencyString, lpStakingConfig, slippage])\n\n const queryKey = useMemo(() => {\n if (!zapInputData) return null\n return [\n 'zapBondDetails',\n zapInputData.chain,\n zapInputData.user,\n zapInputData.lpData.lpType,\n zapInputData.lpData.fromToken,\n zapInputData.lpData.fromAmount,\n zapInputData.lpData.slippage,\n ]\n }, [zapInputData])\n\n const fetchZapDetails = async () => {\n console.log('fetching zap ')\n // The campaign fixes the tick range around the current pool price, so it's read right before each quote\n const res = await multicall(chainId, APE_BOND_POSITION_ADAPTER_ABI, [\n { address: lpStakingConfig!.adapter, name: 'campaignRange', params: [lpStakingConfig!.campaignId] },\n ])\n if (!res[0]) throw new Error('Could not read the campaign tick range')\n\n const [tickLower, tickUpper] = res[0]\n\n const response = await apiPost<any>(SOUL_ZAP_API, {\n ...zapInputData,\n lpData: { ...zapInputData!.lpData, tickLower: Number(tickLower), tickUpper: Number(tickUpper) },\n })\n return response?.result?.data ?? response\n }\n\n const {\n data: response,\n isLoading,\n isFetching,\n error,\n } = useQuery({\n queryKey: [QUERY_KEYS.ZAP_TOKEN_QUOTE, queryKey],\n queryFn: fetchZapDetails,\n refetchInterval: 60000, // i.e. 60 sec\n staleTime: 60000,\n enabled: !!queryKey,\n retry: 1,\n })\n const zapError = !!error\n\n const tokenList = zapInputTokens[chainId] ? zapInputTokens[chainId] : []\n\n // toToken0 data\n const toToken0Estimate: string | undefined = response?.lpQuote?.token0?.fromAmountEstimate\n const toToken0 = [...tokenList, principalToken]?.find(\n (token) => token?.address?.[chainId]?.toLowerCase() === response?.lpQuote?.token0?.address?.toLowerCase(),\n )\n const toToken0Price = useCurrencyPrice(toToken0 ?? null, chainId)\n\n // toToken1 data\n const toToken1Estimate: string | undefined = response?.lpQuote?.token1?.fromAmountEstimate\n const toToken1 = zapInputTokens[chainId]?.find(\n (token) => token.address[chainId]?.toLowerCase() === response?.lpQuote?.token1?.address?.toLowerCase(),\n )\n const toToken1Price = useCurrencyPrice(toToken1 ?? null, chainId)\n\n let toToken0USD =\n Number(formatUnits(toToken0Estimate ?? '0', toToken0?.decimals![chainId] ?? 18)) * (toToken0Price?.price ?? 0) // this is amount of swap output, converted to usd price\n\n if (response?.lpQuote?.token0?.fromAmountUSD) {\n toToken0USD = Number(response?.lpQuote?.token0?.fromAmountUSD)\n }\n\n let toToken1USD =\n Number(formatUnits(toToken1Estimate ?? '0', toToken1?.decimals![chainId] ?? 18)) * (toToken1Price?.price ?? 0) // this is amount of swap output, converted to usd price\n\n if (response?.lpQuote?.token1?.fromAmountUSD) {\n toToken1USD = Number(response?.lpQuote?.token1?.fromAmountUSD)\n }\n\n const youSpendUSD = toToken0USD + toToken1USD // youSpendUSD\n const estimatedDepositAmount = youSpendUSD / Number(bond?.principalTokenPrice ?? '0')\n\n const isWrap =\n inputCurrency === 'NATIVE' &&\n bond?.lpToken?.address?.[chainId]?.toLowerCase() === WNATIVE[chainId]?.address?.[chainId]?.toLowerCase()\n\n const isPrincipalToken =\n inputCurrency !== 'NATIVE' && inputCurrency?.address[chainId] === principalToken.address[chainId]\n\n const estimatedDepositAmountToReturn =\n isWrap || isPrincipalToken\n ? (Number(typedValue || '0') * ((100 - bond?.tierBoostRate!) / 100)).toString()\n : estimatedDepositAmount.toString()\n\n const trueBondPrice: string | undefined = response?.protocolQuote?.trueBondPrice\n\n // DEBUG: log tierOptimization when present\n if (response?.protocolQuote?.tierOptimization) {\n const tier = response.protocolQuote.tierOptimization\n const decimals = principalToken?.decimals?.[chainId] ?? 18\n const cost = Number(formatUnits(tier.tierCost, decimals))\n const input = Number(formatUnits(tier.bondInput, decimals))\n const profit = Number(formatUnits(tier.profit, decimals))\n console.log('[ZAP] tierOptimization:', {\n tier: `${tier.previousTier} → ${tier.newTier}`,\n cost: cost.toFixed(6),\n bondInput: input.toFixed(6),\n profit: profit.toFixed(6),\n })\n }\n\n const zapLoading = isDebouncing || isLoading || isFetching\n if (zapLoading) return [true, undefined, '', false, undefined]\n\n return [zapLoading, response, estimatedDepositAmountToReturn, zapError, trueBondPrice]\n}\n\nexport default useSoulZapLpStakingQuote\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAgBA,MAAM,wBAAwB,GAAG,CAC/B,UAAkB,EAClB,aAA2C,EAC3C,IAA2B,EAC3B,OAAgB,KAC+F;IAC/G,MAAM,cAAc,GAAG,WAAW,CAAC,UAAU,EAAE,GAAG,CAAC;AACnD,IAAA,MAAM,YAAY,GAAG,UAAU,KAAK,cAAc;IAClD,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,WAAW,EAAE;AAE/C,IAAA,MAAM,cAAc,GAAG,IAAI,EAAE,OAAgB;AAC7C,IAAA,MAAM,OAAO,GAAG,IAAI,EAAE,OAAkB;AACxC,IAAA,MAAM,mBAAmB,GACvB,aAAa,KAAK,QAAQ,GAAG,4CAA4C,GAAG,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC;AAC7G,IAAA,MAAM,qBAAqB,GAAG,aAAa,KAAK,QAAQ,GAAG,EAAE,GAAG,aAAa,EAAE,QAAS,CAAC,OAAO,CAAC;AACjG,IAAA,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC;AAExC,IAAA,MAAM,iBAAiB,GAAG,UAAU,CAAC,cAAc,IAAI,GAAG,EAAE,qBAAqB,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE;AACnG,IAAA,MAAM,eAAe,GAAG,IAAI,EAAE,eAAe;AAE7C,IAAA,MAAM,YAAY,GAAG,OAAO,CAAC,MAAK;AAChC,QAAA,IACE,SAAS;YACT,mBAAmB;YACnB,qBAAqB;AACrB,YAAA,iBAAiB,KAAK,KAAK;AAC3B,YAAA,iBAAiB,KAAK,GAAG;AACzB,YAAA,eAAe,EACf;YACA,OAAO;AACL,gBAAA,KAAK,EAAE,SAAS;gBAChB,SAAS,EAAE,OAAO,IAAI,4CAA4C;gBAClE,IAAI,EAAE,OAAO,IAAI,4CAA4C;AAC7D,gBAAA,UAAU,EAAE,SAAS;AACrB,gBAAA,MAAM,EAAE;AACN,oBAAA,SAAS,EAAE,mBAAmB;AAC9B,oBAAA,UAAU,EAAE,iBAAiB;oBAC7B,MAAM,EAAE,eAAe,CAAC,MAAM;oBAC9B,eAAe,EAAE,eAAe,CAAC,eAAe;oBAChD,IAAI,EAAE,eAAe,CAAC,IAAI;oBAC1B,QAAQ;oBACR,SAAS,EAAE,GAAG;oBACd,SAAS,EAAE,GAAG;AACf,iBAAA;AACD,gBAAA,YAAY,EAAE;AACZ,oBAAA,QAAQ,EAAE,aAAa;oBACvB,OAAO,EAAE,eAAe,CAAC,OAAO;oBAChC,UAAU,EAAE,eAAe,CAAC,UAAU;AACvC,iBAAA;aACF;QACH;AACF,IAAA,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC;AAElH,IAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAK;AAC5B,QAAA,IAAI,CAAC,YAAY;AAAE,YAAA,OAAO,IAAI;QAC9B,OAAO;YACL,gBAAgB;AAChB,YAAA,YAAY,CAAC,KAAK;AAClB,YAAA,YAAY,CAAC,IAAI;YACjB,YAAY,CAAC,MAAM,CAAC,MAAM;YAC1B,YAAY,CAAC,MAAM,CAAC,SAAS;YAC7B,YAAY,CAAC,MAAM,CAAC,UAAU;YAC9B,YAAY,CAAC,MAAM,CAAC,QAAQ;SAC7B;AACH,IAAA,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;AAElB,IAAA,MAAM,eAAe,GAAG,YAAW;AACjC,QAAA,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;;QAE5B,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,6BAA6B,EAAE;AAClE,YAAA,EAAE,OAAO,EAAE,eAAgB,CAAC,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC,eAAgB,CAAC,UAAU,CAAC,EAAE;AACpG,SAAA,CAAC;AACF,QAAA,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC;QAEtE,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;AAErC,QAAA,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAM,YAAY,EAAE;AAChD,YAAA,GAAG,YAAY;YACf,MAAM,EAAE,EAAE,GAAG,YAAa,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE;AAChG,SAAA,CAAC;AACF,QAAA,OAAO,QAAQ,EAAE,MAAM,EAAE,IAAI,IAAI,QAAQ;AAC3C,IAAA,CAAC;AAED,IAAA,MAAM,EACJ,IAAI,EAAE,QAAQ,EACd,SAAS,EACT,UAAU,EACV,KAAK,GACN,GAAG,QAAQ,CAAC;AACX,QAAA,QAAQ,EAAE,CAAC,UAAU,CAAC,eAAe,EAAE,QAAQ,CAAC;AAChD,QAAA,OAAO,EAAE,eAAe;QACxB,eAAe,EAAE,KAAK;AACtB,QAAA,SAAS,EAAE,KAAK;QAChB,OAAO,EAAE,CAAC,CAAC,QAAQ;AACnB,QAAA,KAAK,EAAE,CAAC;AACT,KAAA,CAAC;AACF,IAAA,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK;AAExB,IAAA,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE;;IAGxE,MAAM,gBAAgB,GAAuB,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,kBAAkB;AAC1F,IAAA,MAAM,QAAQ,GAAG,CAAC,GAAG,SAAS,EAAE,cAAc,CAAC,EAAE,IAAI,CACnD,CAAC,KAAK,KAAK,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,EAAE,WAAW,EAAE,KAAK,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAC1G;IACD,MAAM,aAAa,GAAG,gBAAgB,CAAC,QAAQ,IAAI,IAAI,EAAE,OAAO,CAAC;;IAGjE,MAAM,gBAAgB,GAAuB,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,kBAAkB;AAC1F,IAAA,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,EAAE,IAAI,CAC5C,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,KAAK,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CACvG;IACD,MAAM,aAAa,GAAG,gBAAgB,CAAC,QAAQ,IAAI,IAAI,EAAE,OAAO,CAAC;AAEjE,IAAA,IAAI,WAAW,GACb,MAAM,CAAC,WAAW,CAAC,gBAAgB,IAAI,GAAG,EAAE,QAAQ,EAAE,QAAS,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,aAAa,EAAE,KAAK,IAAI,CAAC,CAAC,CAAA;IAEhH,IAAI,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE;QAC5C,WAAW,GAAG,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC;IAChE;AAEA,IAAA,IAAI,WAAW,GACb,MAAM,CAAC,WAAW,CAAC,gBAAgB,IAAI,GAAG,EAAE,QAAQ,EAAE,QAAS,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,aAAa,EAAE,KAAK,IAAI,CAAC,CAAC,CAAA;IAEhH,IAAI,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE;QAC5C,WAAW,GAAG,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC;IAChE;AAEA,IAAA,MAAM,WAAW,GAAG,WAAW,GAAG,WAAW,CAAA;AAC7C,IAAA,MAAM,sBAAsB,GAAG,WAAW,GAAG,MAAM,CAAC,IAAI,EAAE,mBAAmB,IAAI,GAAG,CAAC;AAErF,IAAA,MAAM,MAAM,GACV,aAAa,KAAK,QAAQ;QAC1B,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,EAAE,WAAW,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,EAAE,WAAW,EAAE;AAE1G,IAAA,MAAM,gBAAgB,GACpB,aAAa,KAAK,QAAQ,IAAI,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC;AAEnG,IAAA,MAAM,8BAA8B,GAClC,MAAM,IAAI;UACN,CAAC,MAAM,CAAC,UAAU,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,EAAE,aAAc,IAAI,GAAG,CAAC,EAAE,QAAQ;AAC7E,UAAE,sBAAsB,CAAC,QAAQ,EAAE;AAEvC,IAAA,MAAM,aAAa,GAAuB,QAAQ,EAAE,aAAa,EAAE,aAAa;;AAGhF,IAAA,IAAI,QAAQ,EAAE,aAAa,EAAE,gBAAgB,EAAE;AAC7C,QAAA,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,gBAAgB;QACpD,MAAM,QAAQ,GAAG,cAAc,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE;AAC1D,QAAA,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACzD,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC3D,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AACzD,QAAA,OAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE;YACrC,IAAI,EAAE,GAAG,IAAI,CAAC,YAAY,CAAA,GAAA,EAAM,IAAI,CAAC,OAAO,CAAA,CAAE;AAC9C,YAAA,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AACrB,YAAA,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC3B,YAAA,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AAC1B,SAAA,CAAC;IACJ;AAEA,IAAA,MAAM,UAAU,GAAG,YAAY,IAAI,SAAS,IAAI,UAAU;AAC1D,IAAA,IAAI,UAAU;QAAE,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC;IAE9D,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE,8BAA8B,EAAE,QAAQ,EAAE,aAAa,CAAC;AACxF;;;;"}
1
+ {"version":3,"file":"useSoulZapLpStakingQuote.js","sources":["../../../../../src/adapters/evm/state/lpStaking/useSoulZapLpStakingQuote.ts"],"sourcesContent":["import { useMemo } from 'react'\nimport { ChainId, Token } from '@ape.swap/apeswap-lists'\nimport { getChainParam } from '../../../../state/zap/getChainParam'\nimport { apiPost } from '../../../../utils/httpClient'\nimport { useQuery } from '@tanstack/react-query'\nimport { QUERY_KEYS } from '../../../../config/constants/queryKeys'\nimport useCurrencyPrice from '../../../../state/price/useCurrencyPrice'\nimport { BondsData } from '../../../../types/bonds'\nimport { useSlippage } from '../../../../state/slippage/useSlippage'\nimport useDebounce from '../../../../hooks/useDebounce'\nimport { WNATIVE, zapInputTokens } from '@ape.swap/apeswap-lists'\nimport { SOUL_ZAP_API } from '../../../../config/constants/variables'\nimport { formatUnits, parseUnits } from '../../../../utils/fixedPoint'\nimport multicall from '../../utils/multicall'\nimport APE_BOND_POSITION_ADAPTER_ABI from '../../../../config/abi/apeBondPositionAdapter.json'\n\nconst useSoulZapLpStakingQuote = (\n typedValue: string,\n inputCurrency: 'NATIVE' | Token | undefined,\n bond: BondsData | undefined,\n account?: string,\n): [loading: boolean, response: any, depositAmount: string, error: boolean, trueBondPrice: string | undefined] => {\n const debouncedInput = useDebounce(typedValue, 500)\n const isDebouncing = typedValue !== debouncedInput\n const { evmSlippage: slippage } = useSlippage()\n\n const principalToken = bond?.lpToken as Token\n const chainId = bond?.chainId as ChainId\n const inputCurrencyString =\n inputCurrency === 'NATIVE' ? '0x0000000000000000000000000000000000000000' : inputCurrency?.address[chainId]\n const inputCurrencyDecimals = inputCurrency === 'NATIVE' ? 18 : inputCurrency?.decimals![chainId]\n const chainName = getChainParam(chainId)\n\n const bigishInputAmount = parseUnits(debouncedInput ?? '0', inputCurrencyDecimals ?? 18).toString()\n const lpStakingConfig = bond?.lpStakingConfig\n\n const zapInputData = useMemo(() => {\n if (\n chainName &&\n inputCurrencyString &&\n inputCurrencyDecimals &&\n bigishInputAmount !== 'NaN' &&\n bigishInputAmount !== '0' &&\n lpStakingConfig\n ) {\n return {\n chain: chainName,\n recipient: account ?? '0x0000000000000000000000000000000000000000',\n user: account ?? '0x0000000000000000000000000000000000000000',\n integrator: 'apebond',\n lpData: {\n fromToken: inputCurrencyString,\n fromAmount: bigishInputAmount,\n lpType: lpStakingConfig.lpType,\n positionManager: lpStakingConfig.positionManager,\n pool: lpStakingConfig.pool,\n slippage,\n tickLower: '0', //TODO add this\n tickUpper: '0', //TODO add this\n },\n protocolData: {\n protocol: 'RealFinance',\n adapter: lpStakingConfig.adapter,\n campaignId: lpStakingConfig.campaignId,\n },\n }\n }\n }, [account, bigishInputAmount, chainName, inputCurrencyDecimals, inputCurrencyString, lpStakingConfig, slippage])\n\n const queryKey = useMemo(() => {\n if (!zapInputData) return null\n return [\n 'zapLpStakingDetails',\n zapInputData.chain,\n zapInputData.user,\n zapInputData.lpData.lpType,\n zapInputData.lpData.fromToken,\n zapInputData.lpData.fromAmount,\n zapInputData.lpData.slippage,\n zapInputData.lpData.pool,\n zapInputData.lpData.positionManager,\n zapInputData.protocolData.adapter,\n zapInputData.protocolData.campaignId,\n ]\n }, [zapInputData])\n\n const fetchZapDetails = async () => {\n console.log('fetching zap ')\n // The campaign fixes the tick range around the current pool price, so it's read right before each quote\n const res = await multicall(chainId, APE_BOND_POSITION_ADAPTER_ABI, [\n { address: lpStakingConfig!.adapter, name: 'campaignRange', params: [lpStakingConfig!.campaignId] },\n ])\n if (!res[0]) throw new Error('Could not read the campaign tick range')\n\n const [tickLower, tickUpper] = res[0]\n\n const response = await apiPost<any>(SOUL_ZAP_API, {\n ...zapInputData,\n lpData: { ...zapInputData!.lpData, tickLower: Number(tickLower), tickUpper: Number(tickUpper) },\n })\n return response?.result?.data ?? response\n }\n\n const {\n data: response,\n isLoading,\n isFetching,\n error,\n } = useQuery({\n queryKey: [QUERY_KEYS.ZAP_TOKEN_QUOTE, queryKey],\n queryFn: fetchZapDetails,\n refetchInterval: 60000, // i.e. 60 sec\n staleTime: 60000,\n enabled: !!queryKey,\n retry: 1,\n })\n const zapError = !!error\n\n const tokenList = zapInputTokens[chainId] ? zapInputTokens[chainId] : []\n\n // toToken0 data\n const toToken0Estimate: string | undefined = response?.lpQuote?.token0?.fromAmountEstimate\n const toToken0 = [...tokenList, principalToken]?.find(\n (token) => token?.address?.[chainId]?.toLowerCase() === response?.lpQuote?.token0?.address?.toLowerCase(),\n )\n const toToken0Price = useCurrencyPrice(toToken0 ?? null, chainId)\n\n // toToken1 data\n const toToken1Estimate: string | undefined = response?.lpQuote?.token1?.fromAmountEstimate\n const toToken1 = zapInputTokens[chainId]?.find(\n (token) => token.address[chainId]?.toLowerCase() === response?.lpQuote?.token1?.address?.toLowerCase(),\n )\n const toToken1Price = useCurrencyPrice(toToken1 ?? null, chainId)\n\n let toToken0USD =\n Number(formatUnits(toToken0Estimate ?? '0', toToken0?.decimals![chainId] ?? 18)) * (toToken0Price?.price ?? 0) // this is amount of swap output, converted to usd price\n\n if (response?.lpQuote?.token0?.fromAmountUSD) {\n toToken0USD = Number(response?.lpQuote?.token0?.fromAmountUSD)\n }\n\n let toToken1USD =\n Number(formatUnits(toToken1Estimate ?? '0', toToken1?.decimals![chainId] ?? 18)) * (toToken1Price?.price ?? 0) // this is amount of swap output, converted to usd price\n\n if (response?.lpQuote?.token1?.fromAmountUSD) {\n toToken1USD = Number(response?.lpQuote?.token1?.fromAmountUSD)\n }\n\n const youSpendUSD = toToken0USD + toToken1USD // youSpendUSD\n const estimatedDepositAmount = youSpendUSD / Number(bond?.principalTokenPrice ?? '0')\n\n const isWrap =\n inputCurrency === 'NATIVE' &&\n bond?.lpToken?.address?.[chainId]?.toLowerCase() === WNATIVE[chainId]?.address?.[chainId]?.toLowerCase()\n\n const isPrincipalToken =\n inputCurrency !== 'NATIVE' && inputCurrency?.address[chainId] === principalToken.address[chainId]\n\n const estimatedDepositAmountToReturn =\n isWrap || isPrincipalToken\n ? (Number(typedValue || '0') * ((100 - bond?.tierBoostRate!) / 100)).toString()\n : estimatedDepositAmount.toString()\n\n const trueBondPrice: string | undefined = response?.protocolQuote?.trueBondPrice\n\n // DEBUG: log tierOptimization when present\n if (response?.protocolQuote?.tierOptimization) {\n const tier = response.protocolQuote.tierOptimization\n const decimals = principalToken?.decimals?.[chainId] ?? 18\n const cost = Number(formatUnits(tier.tierCost, decimals))\n const input = Number(formatUnits(tier.bondInput, decimals))\n const profit = Number(formatUnits(tier.profit, decimals))\n console.log('[ZAP] tierOptimization:', {\n tier: `${tier.previousTier} → ${tier.newTier}`,\n cost: cost.toFixed(6),\n bondInput: input.toFixed(6),\n profit: profit.toFixed(6),\n })\n }\n\n const zapLoading = isDebouncing || isLoading || isFetching\n if (zapLoading) return [true, undefined, '', false, undefined]\n\n return [zapLoading, response, estimatedDepositAmountToReturn, zapError, trueBondPrice]\n}\n\nexport default useSoulZapLpStakingQuote\n"],"names":[],"mappings":"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"}
@@ -30,7 +30,7 @@ import LpBondModalHeader from './LpBondModalHeader.js';
30
30
  import LpStakingEstimations from './LpStakingEstimations.js';
31
31
  import useSortedZapList from '../../../../hooks/useSortedZapList.js';
32
32
  import { getSymbol } from '../../../../utils/getNativeTicker.js';
33
- import { formatUSDNumber } from '../../../../utils/displayHelpers.js';
33
+ import { formatUSDNumber, getMaxBuy } from '../../../../utils/displayHelpers.js';
34
34
 
35
35
  /**
36
36
  * Buy form of LP staking bonds (`billType === 'lpStaking'`). Kept apart from the regular EVM BuyComponent because the
@@ -75,6 +75,17 @@ const BuyComponentLpStaking = ({ onDismiss, bondAddress, bondChain, handlePurcha
75
75
  const spendAmount = parseFloat(inputValue) || 0;
76
76
  const youSpendString = `${spendAmount.toLocaleString()} ${getSymbol(inputToken, bondData?.chainId)}${inputTokenPrice ? ` ($${formatUSDNumber((spendAmount * inputTokenPrice).toString())})` : ''}`;
77
77
  const isZapSupported = false;
78
+ // Every purchase goes through the zap, so it can't be sent without a quote to send
79
+ const hasZapQuote = !zapError && !!zapData?.txData;
80
+ // maxPayout and the bond's remaining capacity are in the pool's stablecoin (lpToken1), counted at $1. Paying with it
81
+ // needs no price; other tokens are converted with their USD price, and can't be checked without one (the price
82
+ // guard still reverts the tx).
83
+ const stablecoinAddress = bondData?.lpStakingConfig?.lpToken1?.address?.[bondChain]?.toLowerCase();
84
+ const isPayingWithStablecoin = inputToken !== 'NATIVE' && inputToken?.address?.[bondChain]?.toLowerCase() === stablecoinAddress;
85
+ const spendInStablecoin = isPayingWithStablecoin ? spendAmount : spendAmount * (inputTokenPrice ?? 0);
86
+ const maxBuy = getMaxBuy(bondData, true);
87
+ // 0 when the limits couldn't be read; the price guard still applies then
88
+ const exceedsMaxBuy = maxBuy > 0 && spendInStablecoin > maxBuy;
78
89
  // Once the buy tx is confirmed, report the new position's NFT id so ModalHandlerLpStaking can show it. The adapter's
79
90
  // deposit event has it: topics = [event, tokenId, campaignId, buyer]. It's the token_id REAL's API lists the
80
91
  // position under, which is the bill's id.
@@ -126,7 +137,7 @@ const BuyComponentLpStaking = ({ onDismiss, bondAddress, bondChain, handlePurcha
126
137
  });
127
138
  };
128
139
  const handleBuy = async () => {
129
- if (!bondData || !bondAddress || !bondChain)
140
+ if (!bondData || !bondAddress || !bondChain || !hasZapQuote)
130
141
  return;
131
142
  if (isWrongChain) {
132
143
  try {
@@ -195,16 +206,23 @@ const BuyComponentLpStaking = ({ onDismiss, bondAddress, bondChain, handlePurcha
195
206
  bondData?.soldOut ||
196
207
  isEmptyInput ||
197
208
  exceedsBalance ||
209
+ exceedsMaxBuy ||
198
210
  SDKConfig.blockSales ||
199
- zapLoading, onClick: isApproved ? handleBuy : handleApprove, children: exceedsBalance
211
+ zapLoading ||
212
+ // Approving doesn't need the quote, buying does
213
+ (isApproved && !hasZapQuote), onClick: isApproved ? handleBuy : handleApprove, children: exceedsBalance
200
214
  ? 'Exceeds balance'
201
215
  : isEmptyInput
202
216
  ? 'Insert amount'
203
- : isApproved
204
- ? zapLoading
205
- ? 'Loading'
206
- : 'buy'
207
- : 'approve' })) }) })] }) })) : (jsx(Fragment, {}));
217
+ : exceedsMaxBuy
218
+ ? 'Exceeds Max Buy. Reduce amount'
219
+ : isApproved
220
+ ? zapLoading
221
+ ? 'Loading'
222
+ : hasZapQuote
223
+ ? 'buy'
224
+ : 'Quote unavailable'
225
+ : 'approve' })) }) })] }) })) : (jsx(Fragment, {}));
208
226
  };
209
227
  var BuyComponentLpStaking$1 = React.memo(BuyComponentLpStaking);
210
228