@ape.swap/bonds-sdk 5.1.48 → 5.1.49-test-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/README.md +14 -7
  2. package/dist/components/ConnectAptosWalletButton/ConnectAptosWalletButton.d.ts +4 -0
  3. package/dist/components/ConnectAptosWalletButton/ConnectAptosWalletButton.js +39 -0
  4. package/dist/components/ConnectAptosWalletButton/ConnectAptosWalletButton.js.map +1 -0
  5. package/dist/components/ConnectSuiWalletButton/ConnectSuiWalletButton.d.ts +5 -0
  6. package/dist/components/ConnectoToVmBanners/ConnectToAptosBanner.d.ts +1 -0
  7. package/dist/components/ConnectoToVmBanners/ConnectToAptosBanner.js +49 -0
  8. package/dist/components/ConnectoToVmBanners/ConnectToAptosBanner.js.map +1 -0
  9. package/dist/components/ConnectoToVmBanners/ConnectToEvmBanner.js +11 -15
  10. package/dist/components/ConnectoToVmBanners/ConnectToEvmBanner.js.map +1 -1
  11. package/dist/components/ConnectoToVmBanners/ConnectToSolanaBanner.js +13 -17
  12. package/dist/components/ConnectoToVmBanners/ConnectToSolanaBanner.js.map +1 -1
  13. package/dist/components/ConnectoToVmBanners/ConnectToSuiBanner.d.ts +1 -0
  14. package/dist/components/ConnectoToVmBanners/ConnectToSuiBanner.js +44 -0
  15. package/dist/components/ConnectoToVmBanners/ConnectToSuiBanner.js.map +1 -0
  16. package/dist/components/TokenInfoAndName/index.js +2 -0
  17. package/dist/components/TokenInfoAndName/index.js.map +1 -1
  18. package/dist/components/TokenSelectorPanel/index.js +11 -1
  19. package/dist/components/TokenSelectorPanel/index.js.map +1 -1
  20. package/dist/components/Tooltip/Tooltip.js +11 -3
  21. package/dist/components/Tooltip/Tooltip.js.map +1 -1
  22. package/dist/components/uikit-sdk/Svg/index.js +6 -0
  23. package/dist/components/uikit-sdk/Svg/index.js.map +1 -1
  24. package/dist/components/uikit-sdk/Svg/tokens/APTOS.d.ts +4 -0
  25. package/dist/components/uikit-sdk/Svg/tokens/APTOS.js +8 -0
  26. package/dist/components/uikit-sdk/Svg/tokens/APTOS.js.map +1 -0
  27. package/dist/components/uikit-sdk/Svg/tokens/SUI.d.ts +4 -0
  28. package/dist/components/uikit-sdk/Svg/tokens/SUI.js +8 -0
  29. package/dist/components/uikit-sdk/Svg/tokens/SUI.js.map +1 -0
  30. package/dist/components/uikit-sdk/Svg/types.d.ts +2 -0
  31. package/dist/components/uikit-sdk/Svg/types.js +2 -0
  32. package/dist/components/uikit-sdk/Svg/types.js.map +1 -1
  33. package/dist/components/uikit-sdk/TokenImage/index.js +15 -3
  34. package/dist/components/uikit-sdk/TokenImage/index.js.map +1 -1
  35. package/dist/config/constants/addresses.d.ts +1 -1
  36. package/dist/config/constants/addresses.js +2 -0
  37. package/dist/config/constants/addresses.js.map +1 -1
  38. package/dist/config/constants/aptosZapTokens.d.ts +23 -0
  39. package/dist/config/constants/aptosZapTokens.js +66 -0
  40. package/dist/config/constants/aptosZapTokens.js.map +1 -0
  41. package/dist/config/constants/chains.d.ts +3 -1
  42. package/dist/config/constants/chains.js +12 -0
  43. package/dist/config/constants/chains.js.map +1 -1
  44. package/dist/config/constants/networks.js +9 -0
  45. package/dist/config/constants/networks.js.map +1 -1
  46. package/dist/config/constants/queryKeys.js +23 -1
  47. package/dist/config/constants/queryKeys.js.map +1 -1
  48. package/dist/config/constants/suiZapTokens.d.ts +14 -0
  49. package/dist/config/constants/suiZapTokens.js +41 -0
  50. package/dist/config/constants/suiZapTokens.js.map +1 -0
  51. package/dist/config/constants/tokens.js +48 -0
  52. package/dist/config/constants/tokens.js.map +1 -0
  53. package/dist/config/constants/variables.d.ts +1 -1
  54. package/dist/config/constants/variables.js +2 -0
  55. package/dist/config/constants/variables.js.map +1 -1
  56. package/dist/constants/aptosConstants.d.ts +20 -0
  57. package/dist/constants/aptosConstants.js +78 -0
  58. package/dist/constants/aptosConstants.js.map +1 -0
  59. package/dist/constants/suiConstants.d.ts +18 -0
  60. package/dist/constants/suiConstants.js +61 -0
  61. package/dist/constants/suiConstants.js.map +1 -0
  62. package/dist/hooks/accounts/useAPTAccount.d.ts +30 -0
  63. package/dist/hooks/accounts/useAPTAccount.js +39 -0
  64. package/dist/hooks/accounts/useAPTAccount.js.map +1 -0
  65. package/dist/hooks/accounts/useSUIAccount.d.ts +7 -0
  66. package/dist/hooks/accounts/useSUIAccount.js +46 -0
  67. package/dist/hooks/accounts/useSUIAccount.js.map +1 -0
  68. package/dist/hooks/useMonitorTx.d.ts +2 -21
  69. package/dist/hooks/useMonitorTx.js.map +1 -1
  70. package/dist/hooks/useSortedZapList.js +7 -2
  71. package/dist/hooks/useSortedZapList.js.map +1 -1
  72. package/dist/hooks/useTokenFromZapList.js +1 -0
  73. package/dist/hooks/useTokenFromZapList.js.map +1 -1
  74. package/dist/providers/AptosWalletProvider.d.ts +5 -0
  75. package/dist/providers/SuiWalletProvider.d.ts +5 -0
  76. package/dist/state/balance/useCurrencyBalance.js +9 -0
  77. package/dist/state/balance/useCurrencyBalance.js.map +1 -1
  78. package/dist/state/balance/useCurrencyBalanceAptos.d.ts +14 -0
  79. package/dist/state/balance/useCurrencyBalanceAptos.js +75 -0
  80. package/dist/state/balance/useCurrencyBalanceAptos.js.map +1 -0
  81. package/dist/state/balance/useCurrencyBalanceSui.d.ts +14 -0
  82. package/dist/state/balance/useCurrencyBalanceSui.js +42 -0
  83. package/dist/state/balance/useCurrencyBalanceSui.js.map +1 -0
  84. package/dist/state/balance/useUserTokensBalance.js +19 -1
  85. package/dist/state/balance/useUserTokensBalance.js.map +1 -1
  86. package/dist/state/bonds/aptosBondsConfig.d.ts +4 -0
  87. package/dist/state/bonds/aptosBondsConfig.js +114 -0
  88. package/dist/state/bonds/aptosBondsConfig.js.map +1 -0
  89. package/dist/state/bonds/fetchBillsUserAptos.d.ts +4 -0
  90. package/dist/state/bonds/fetchBillsUserAptos.js +187 -0
  91. package/dist/state/bonds/fetchBillsUserAptos.js.map +1 -0
  92. package/dist/state/bonds/fetchBillsUserSui.d.ts +4 -0
  93. package/dist/state/bonds/fetchBillsUserSui.js +287 -0
  94. package/dist/state/bonds/fetchBillsUserSui.js.map +1 -0
  95. package/dist/state/bonds/fetchBondsDataAptos.d.ts +12 -0
  96. package/dist/state/bonds/fetchBondsDataAptos.js +114 -0
  97. package/dist/state/bonds/fetchBondsDataAptos.js.map +1 -0
  98. package/dist/state/bonds/fetchBondsDataSui.d.ts +13 -0
  99. package/dist/state/bonds/fetchBondsDataSui.js +205 -0
  100. package/dist/state/bonds/fetchBondsDataSui.js.map +1 -0
  101. package/dist/state/bonds/suiBondsConfig.d.ts +4 -0
  102. package/dist/state/bonds/suiBondsConfig.js +113 -0
  103. package/dist/state/bonds/suiBondsConfig.js.map +1 -0
  104. package/dist/state/bonds/useBondsData.js +32 -8
  105. package/dist/state/bonds/useBondsData.js.map +1 -1
  106. package/dist/state/bonds/useBondsList.js +15 -2
  107. package/dist/state/bonds/useBondsList.js.map +1 -1
  108. package/dist/state/bonds/useUserBonds.d.ts +1 -1
  109. package/dist/state/bonds/useUserBonds.js +34 -12
  110. package/dist/state/bonds/useUserBonds.js.map +1 -1
  111. package/dist/state/bonds/utils.js +8 -0
  112. package/dist/state/bonds/utils.js.map +1 -1
  113. package/dist/state/price/useCurrencyPrice.js +2 -1
  114. package/dist/state/price/useCurrencyPrice.js.map +1 -1
  115. package/dist/state/tiers/useTierPoints.js +1 -4
  116. package/dist/state/tiers/useTierPoints.js.map +1 -1
  117. package/dist/state/tokenPrices/useTokenPrices.js +16 -1
  118. package/dist/state/tokenPrices/useTokenPrices.js.map +1 -1
  119. package/dist/state/useSDKConfig.d.ts +4 -0
  120. package/dist/state/useSDKConfig.js.map +1 -1
  121. package/dist/state/zap/useAptosZapQuote.d.ts +28 -0
  122. package/dist/state/zap/useAptosZapQuote.js +83 -0
  123. package/dist/state/zap/useAptosZapQuote.js.map +1 -0
  124. package/dist/state/zap/useSoulZapBondQuote.js +1 -0
  125. package/dist/state/zap/useSoulZapBondQuote.js.map +1 -1
  126. package/dist/state/zap/useSuiZapQuote.d.ts +24 -0
  127. package/dist/state/zap/useSuiZapQuote.js +119 -0
  128. package/dist/state/zap/useSuiZapQuote.js.map +1 -0
  129. package/dist/types/aptosBonds.d.ts +152 -0
  130. package/dist/types/yourbonds.d.ts +3 -9
  131. package/dist/utils/aptosHelpers.d.ts +80 -0
  132. package/dist/utils/aptosHelpers.js +202 -0
  133. package/dist/utils/aptosHelpers.js.map +1 -0
  134. package/dist/utils/getNativeTicker.js +1 -0
  135. package/dist/utils/getNativeTicker.js.map +1 -1
  136. package/dist/utils/suiHelpers.d.ts +6 -0
  137. package/dist/utils/suiHelpers.js +106 -0
  138. package/dist/utils/suiHelpers.js.map +1 -0
  139. package/dist/views/Bonds/components/BondRows/ActiveBondRows.js +8 -2
  140. package/dist/views/Bonds/components/BondRows/ActiveBondRows.js.map +1 -1
  141. package/dist/views/Bonds/components/BondRows/ModalHandler.js +18 -1
  142. package/dist/views/Bonds/components/BondRows/ModalHandler.js.map +1 -1
  143. package/dist/views/Bonds/components/ChainBanner/ChainBanner.js +29 -0
  144. package/dist/views/Bonds/components/ChainBanner/ChainBanner.js.map +1 -1
  145. package/dist/views/BuyBond/BuyBondModal.js +4 -1
  146. package/dist/views/BuyBond/BuyBondModal.js.map +1 -1
  147. package/dist/views/BuyBond/BuyComponentAptos.d.ts +10 -0
  148. package/dist/views/BuyBond/BuyComponentAptos.js +349 -0
  149. package/dist/views/BuyBond/BuyComponentAptos.js.map +1 -0
  150. package/dist/views/BuyBond/BuyComponentSui.d.ts +10 -0
  151. package/dist/views/BuyBond/BuyComponentSui.js +459 -0
  152. package/dist/views/BuyBond/BuyComponentSui.js.map +1 -0
  153. package/dist/views/BuyBond/components/Estimations.js +2 -1
  154. package/dist/views/BuyBond/components/Estimations.js.map +1 -1
  155. package/dist/views/BuyBond/components/PointsLeftForNextTier/PointsLeftForNextTier.js +8 -23
  156. package/dist/views/BuyBond/components/PointsLeftForNextTier/PointsLeftForNextTier.js.map +1 -1
  157. package/dist/views/YourBonds/YourBonds.js +19 -2
  158. package/dist/views/YourBonds/YourBonds.js.map +1 -1
  159. package/dist/views/YourBonds/components/ClaimAll/ClaimAllModal.js +139 -5
  160. package/dist/views/YourBonds/components/ClaimAll/ClaimAllModal.js.map +1 -1
  161. package/dist/views/YourBonds/components/ClaimAll/index.js +6 -2
  162. package/dist/views/YourBonds/components/ClaimAll/index.js.map +1 -1
  163. package/dist/views/YourBonds/components/UserBondRow/UserBondRowAptos.d.ts +6 -0
  164. package/dist/views/YourBonds/components/UserBondRow/UserBondRowAptos.js +109 -0
  165. package/dist/views/YourBonds/components/UserBondRow/UserBondRowAptos.js.map +1 -0
  166. package/dist/views/YourBonds/components/UserBondRow/UserBondRowSui.d.ts +6 -0
  167. package/dist/views/YourBonds/components/UserBondRow/UserBondRowSui.js +126 -0
  168. package/dist/views/YourBonds/components/UserBondRow/UserBondRowSui.js.map +1 -0
  169. package/dist/views/YourBonds/components/UserBondRow/index.d.ts +2 -0
  170. package/dist/views/YourBondsModal/YourBondsModal.js +3 -1
  171. package/dist/views/YourBondsModal/YourBondsModal.js.map +1 -1
  172. package/dist/views/YourBondsModal/components/Actions/ActionsAptos.d.ts +6 -0
  173. package/dist/views/YourBondsModal/components/Actions/ActionsAptos.js +96 -0
  174. package/dist/views/YourBondsModal/components/Actions/ActionsAptos.js.map +1 -0
  175. package/dist/views/YourBondsModal/components/Actions/ActionsSui.d.ts +6 -0
  176. package/dist/views/YourBondsModal/components/Actions/ActionsSui.js +115 -0
  177. package/dist/views/YourBondsModal/components/Actions/ActionsSui.js.map +1 -0
  178. package/dist/views/YourBondsModal/components/TransferBondModal/TransferActionAptos.d.ts +8 -0
  179. package/dist/views/YourBondsModal/components/TransferBondModal/TransferActionAptos.js +18 -0
  180. package/dist/views/YourBondsModal/components/TransferBondModal/TransferActionAptos.js.map +1 -0
  181. package/dist/views/YourBondsModal/components/TransferBondModal/index.js +2 -1
  182. package/dist/views/YourBondsModal/components/TransferBondModal/index.js.map +1 -1
  183. package/package.json +7 -4
@@ -0,0 +1,114 @@
1
+ import { ChainId, BillArtCollection, BillVersion } from '@ape.swap/apeswap-lists';
2
+ import { APTOS_CONTRACT_ADDRESS } from '../../constants/aptosConstants.js';
3
+ import { APTOS_ZAP_TOKENS } from '../../config/constants/aptosZapTokens.js';
4
+
5
+ // =============================================================================
6
+ // Aptos bonds config — static bond listing for on-chain first architecture
7
+ // =============================================================================
8
+ //
9
+ // api-v2 and realtime-api do NOT support Aptos. Bond listing comes from this
10
+ // static config. Enrichment (prices, discounts, vesting) is read on-chain via
11
+ // bond::market_info view function.
12
+ //
13
+ // TODO(aptos): Replace placeholder addresses with real deployed market addresses.
14
+ // TODO(aptos): Consider indexing BondMarketCreatedEvent for automatic market
15
+ // discovery instead of maintaining this static list.
16
+ //
17
+ // Call sites:
18
+ // - useBondsList.ts → getAptosBondsList()
19
+ // - useTokenPrices.ts → getAptosFallbackPrices()
20
+ const APTOS_KEY = ChainId.APTOS_MAINNET;
21
+ // TODO(aptos): For mainnet launch, update these addresses:
22
+ // 1. APTOS_BOND_MARKET_ADDRESSES → mainnet bond market object addresses
23
+ // 2. APTOS_PAYOUT_TOKEN_ADDRESS → mainnet payout token FA address (real token, not tAPE)
24
+ // 3. APTOS_PRINCIPAL_TOKEN_ADDRESS if principal differs per market
25
+ // Also update APTOS_CONTRACT_ADDRESS_MAINNET in aptosConstants.ts.
26
+ /** Testnet bond market object addresses (bond::market_info). */
27
+ const APTOS_BOND_MARKET_ADDRESSES = [
28
+ '0x9902fa5b2fac9d6665f1f94b66ac72709d63d38b494973089f55de5f11af12da',
29
+ '0xd5b8002990de9cb9de9a6104d51f1d142c66604d7fdc2f38afc01cccc269076f',
30
+ '0xb85b06e858eda8e01cfcebab7fda0dd24e987f41595d94417fdce64ce41e222d',
31
+ '0x5b17d6b52258601f6bc34f46195947a8de4ec21104c77341a0983f6a8249128b',
32
+ ];
33
+ // tAPE payout token metadata
34
+ const APTOS_PAYOUT_TOKEN_ADDRESS = '0xff27a471b7d44e2a8eae1b8693190d4322f4e28cd9a4dd9d8fff7ed74a47556e';
35
+ // APT principal token metadata
36
+ const APTOS_PRINCIPAL_TOKEN_ADDRESS = '0xa';
37
+ const APTOS_BONDS_CONFIG = APTOS_BOND_MARKET_ADDRESSES.map((marketAddress, i) => ({
38
+ index: 99001 + i,
39
+ version: '2.0.0',
40
+ chainId: APTOS_KEY,
41
+ billVersion: BillVersion.V2,
42
+ billType: 'reserve',
43
+ soldOut: false,
44
+ contractAddress: {
45
+ [APTOS_KEY]: marketAddress,
46
+ },
47
+ billNnftAddress: {
48
+ [APTOS_KEY]: `${APTOS_CONTRACT_ADDRESS}::bond_nft::COLLECTION`,
49
+ },
50
+ lpToken: {
51
+ symbol: 'APT',
52
+ address: {
53
+ [APTOS_KEY]: APTOS_PRINCIPAL_TOKEN_ADDRESS,
54
+ },
55
+ decimals: { [APTOS_KEY]: 8 },
56
+ active: true,
57
+ },
58
+ earnToken: {
59
+ symbol: 'tAPE',
60
+ address: {
61
+ [APTOS_KEY]: APTOS_PAYOUT_TOKEN_ADDRESS,
62
+ },
63
+ decimals: { [APTOS_KEY]: 8 },
64
+ active: true,
65
+ },
66
+ billArt: { collection: BillArtCollection.ApeBond_Collection1 },
67
+ shortDescription: 'Aptos bond — on-chain first, no backend dependency.',
68
+ fullDescription: 'Aptos bond operating in on-chain first mode. All market data (prices, discounts, vesting) is read directly from Move view functions. No api-v2 or realtime-api dependency.',
69
+ vestingTerm: 172800, // placeholder; enrichAptosBonds overwrites from market_info
70
+ tags: ['Aptos'],
71
+ }));
72
+ // Fallback prices used until price-api.ape.bond supports Aptos tokens.
73
+ // TODO(aptos): Remove fallback prices when price-api returns Aptos token prices.
74
+ // Update APT and payout token prices to current values before mainnet launch.
75
+ [
76
+ {
77
+ chainId: ChainId.APTOS_MAINNET,
78
+ chainName: 'Aptos',
79
+ tokenAddress: APTOS_PRINCIPAL_TOKEN_ADDRESS,
80
+ name: 'Aptos Coin',
81
+ symbol: 'APT',
82
+ price: 5.5,
83
+ priceSource: 'fallback',
84
+ updatedAt: 0,
85
+ secondsAgoUpdated: 0,
86
+ },
87
+ {
88
+ chainId: ChainId.APTOS_MAINNET,
89
+ chainName: 'Aptos',
90
+ tokenAddress: APTOS_PAYOUT_TOKEN_ADDRESS,
91
+ name: 'Test APE',
92
+ symbol: 'tAPE',
93
+ price: 0.6,
94
+ priceSource: 'fallback',
95
+ updatedAt: 0,
96
+ secondsAgoUpdated: 0,
97
+ },
98
+ // Zap tokens — addresses come from aptosZapTokens.ts (testnet/mainnet aware)
99
+ ...APTOS_ZAP_TOKENS.map((t) => ({
100
+ chainId: ChainId.APTOS_MAINNET,
101
+ chainName: 'Aptos',
102
+ tokenAddress: t.faAddress,
103
+ name: t.name,
104
+ symbol: t.symbol,
105
+ price: t.symbol === 'USDC' || t.symbol === 'USDt' ? 1.0 : 0,
106
+ priceSource: 'fallback',
107
+ updatedAt: 0,
108
+ secondsAgoUpdated: 0,
109
+ })),
110
+ ];
111
+ const getAptosBondsList = () => APTOS_BONDS_CONFIG;
112
+
113
+ export { getAptosBondsList };
114
+ //# sourceMappingURL=aptosBondsConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aptosBondsConfig.js","sources":["../../../src/state/bonds/aptosBondsConfig.ts"],"sourcesContent":["// =============================================================================\n// Aptos bonds config — static bond listing for on-chain first architecture\n// =============================================================================\n//\n// api-v2 and realtime-api do NOT support Aptos. Bond listing comes from this\n// static config. Enrichment (prices, discounts, vesting) is read on-chain via\n// bond::market_info view function.\n//\n// TODO(aptos): Replace placeholder addresses with real deployed market addresses.\n// TODO(aptos): Consider indexing BondMarketCreatedEvent for automatic market\n// discovery instead of maintaining this static list.\n//\n// Call sites:\n// - useBondsList.ts → getAptosBondsList()\n// - useTokenPrices.ts → getAptosFallbackPrices()\n\nimport { BillArtCollection, BillsConfig, BillVersion, ChainId } from '@ape.swap/apeswap-lists'\nimport { APTOS_CONTRACT_ADDRESS } from '../../constants/aptosConstants'\nimport { APTOS_ZAP_TOKENS } from '../../config/constants/aptosZapTokens'\nimport type { TokenPrices } from '../tokenPrices/useTokenPrices'\n\nconst APTOS_KEY = ChainId.APTOS_MAINNET\n\n// TODO(aptos): For mainnet launch, update these addresses:\n// 1. APTOS_BOND_MARKET_ADDRESSES → mainnet bond market object addresses\n// 2. APTOS_PAYOUT_TOKEN_ADDRESS → mainnet payout token FA address (real token, not tAPE)\n// 3. APTOS_PRINCIPAL_TOKEN_ADDRESS if principal differs per market\n// Also update APTOS_CONTRACT_ADDRESS_MAINNET in aptosConstants.ts.\n\n/** Testnet bond market object addresses (bond::market_info). */\nconst APTOS_BOND_MARKET_ADDRESSES = [\n '0x9902fa5b2fac9d6665f1f94b66ac72709d63d38b494973089f55de5f11af12da',\n '0xd5b8002990de9cb9de9a6104d51f1d142c66604d7fdc2f38afc01cccc269076f',\n '0xb85b06e858eda8e01cfcebab7fda0dd24e987f41595d94417fdce64ce41e222d',\n '0x5b17d6b52258601f6bc34f46195947a8de4ec21104c77341a0983f6a8249128b',\n] as const\n\n// tAPE payout token metadata\nconst APTOS_PAYOUT_TOKEN_ADDRESS = '0xff27a471b7d44e2a8eae1b8693190d4322f4e28cd9a4dd9d8fff7ed74a47556e'\n// APT principal token metadata\nconst APTOS_PRINCIPAL_TOKEN_ADDRESS = '0xa'\n\nconst APTOS_BONDS_CONFIG: BillsConfig[] = APTOS_BOND_MARKET_ADDRESSES.map((marketAddress, i) => ({\n index: 99001 + i,\n version: '2.0.0',\n chainId: APTOS_KEY,\n billVersion: BillVersion.V2,\n billType: 'reserve',\n soldOut: false,\n contractAddress: {\n [APTOS_KEY]: marketAddress,\n },\n billNnftAddress: {\n [APTOS_KEY]: `${APTOS_CONTRACT_ADDRESS}::bond_nft::COLLECTION`,\n },\n lpToken: {\n symbol: 'APT',\n address: {\n [APTOS_KEY]: APTOS_PRINCIPAL_TOKEN_ADDRESS,\n },\n decimals: { [APTOS_KEY]: 8 },\n active: true,\n },\n earnToken: {\n symbol: 'tAPE',\n address: {\n [APTOS_KEY]: APTOS_PAYOUT_TOKEN_ADDRESS,\n },\n decimals: { [APTOS_KEY]: 8 },\n active: true,\n },\n billArt: { collection: BillArtCollection.ApeBond_Collection1 },\n shortDescription: 'Aptos bond — on-chain first, no backend dependency.',\n fullDescription:\n 'Aptos bond operating in on-chain first mode. All market data (prices, discounts, vesting) is read directly from Move view functions. No api-v2 or realtime-api dependency.',\n vestingTerm: 172800, // placeholder; enrichAptosBonds overwrites from market_info\n tags: ['Aptos'],\n}))\n\n// Fallback prices used until price-api.ape.bond supports Aptos tokens.\n// TODO(aptos): Remove fallback prices when price-api returns Aptos token prices.\n// Update APT and payout token prices to current values before mainnet launch.\nconst APTOS_FALLBACK_PRICES: TokenPrices[] = [\n {\n chainId: ChainId.APTOS_MAINNET,\n chainName: 'Aptos',\n tokenAddress: APTOS_PRINCIPAL_TOKEN_ADDRESS,\n name: 'Aptos Coin',\n symbol: 'APT',\n price: 5.5,\n priceSource: 'fallback',\n updatedAt: 0,\n secondsAgoUpdated: 0,\n },\n {\n chainId: ChainId.APTOS_MAINNET,\n chainName: 'Aptos',\n tokenAddress: APTOS_PAYOUT_TOKEN_ADDRESS,\n name: 'Test APE',\n symbol: 'tAPE',\n price: 0.6,\n priceSource: 'fallback',\n updatedAt: 0,\n secondsAgoUpdated: 0,\n },\n // Zap tokens — addresses come from aptosZapTokens.ts (testnet/mainnet aware)\n ...APTOS_ZAP_TOKENS.map((t) => ({\n chainId: ChainId.APTOS_MAINNET as ChainId,\n chainName: 'Aptos',\n tokenAddress: t.faAddress,\n name: t.name,\n symbol: t.symbol,\n price: t.symbol === 'USDC' || t.symbol === 'USDt' ? 1.0 : 0,\n priceSource: 'fallback' as const,\n updatedAt: 0,\n secondsAgoUpdated: 0,\n })),\n]\n\nexport const getAptosBondsList = (): BillsConfig[] => APTOS_BONDS_CONFIG\n\nexport const getAptosFallbackPrices = (): TokenPrices[] => APTOS_FALLBACK_PRICES\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { BillsConfig, ChainId } from '@ape.swap/apeswap-lists';
2
+ import type { UserOwnedBillsData } from '../../types/yourbonds';
3
+ import type { TokenPrices } from '../tokenPrices/useTokenPrices';
4
+ export declare function fetchUserOwnedAptosBonds(user: string | undefined, bondData: BillsConfig[], tokenPrices: Partial<Record<ChainId, TokenPrices[]>>, priceApiUrl?: string): Promise<UserOwnedBillsData[]>;
@@ -0,0 +1,187 @@
1
+ import { ChainId } from '@ape.swap/apeswap-lists';
2
+ import { APTOS_PLACEHOLDER_BILL_IMAGE } from '../../constants/aptosConstants.js';
3
+ import axios from 'axios';
4
+ import { readUserBillIds, readBondMarketByBillId, readNftAddressByBillId, readAptosBillInfo, readVestingProgress } from '../../utils/aptosHelpers.js';
5
+
6
+ // =============================================================================
7
+ // fetchUserOwnedAptosBonds — user bills fetcher for the Aptos chain
8
+ // =============================================================================
9
+ //
10
+ // On-chain first: reads user bills directly via Move view functions (no
11
+ // api-v2 dependency). Uses:
12
+ //
13
+ // bond_nft::user_bills(user) → [bill_id, ...]
14
+ // bond_nft::bond_market_by_id(bill_id) → market_addr
15
+ // bond_nft::nft_address(bill_id) → bill_addr
16
+ // bond::bill_info(market, bill_addr) → Bill struct
17
+ // bond_nft::vesting_progress(bill_id) → [total_vested, claimable]
18
+ async function fetchUserOwnedAptosBonds(user, bondData, tokenPrices, priceApiUrl) {
19
+ if (!user)
20
+ return [];
21
+ // Build one `UserOwnedBillsData` per known bond config. We always return
22
+ // the outer shell so downstream code (`getUserBonds` in useUserBonds.ts)
23
+ // can match bills back to their bond config.
24
+ const aptosKey = ChainId.APTOS_MAINNET;
25
+ const aptosPrices = tokenPrices?.[aptosKey] ?? [];
26
+ // Index bonds by lowercased market address for O(1) lookup when matching
27
+ // bill_ids back to their market.
28
+ const bondsByMarket = new Map();
29
+ for (const bond of bondData) {
30
+ const marketAddr = bond.contractAddress[aptosKey];
31
+ if (marketAddr)
32
+ bondsByMarket.set(marketAddr.toLowerCase(), bond);
33
+ }
34
+ // Seed the result with empty shells so every bond is represented.
35
+ const result = bondData.map((bond) => ({
36
+ index: bond.index,
37
+ userOwnedBills: [],
38
+ }));
39
+ const indexByBondIndex = new Map();
40
+ for (const entry of result)
41
+ indexByBondIndex.set(entry.index, entry);
42
+ try {
43
+ const billIds = await readUserBillIds(user);
44
+ if (billIds.length === 0)
45
+ return result;
46
+ // For each bill the user owns, resolve its market, object address, state
47
+ // and vesting progress in parallel. Bills whose market is not in our
48
+ // bondData are silently skipped (they belong to a market the SDK isn't
49
+ // configured to display).
50
+ await Promise.all(billIds.map(async (billId) => {
51
+ try {
52
+ const [marketAddr, billAddr] = await Promise.all([
53
+ readBondMarketByBillId(billId),
54
+ readNftAddressByBillId(billId),
55
+ ]);
56
+ const bond = bondsByMarket.get(marketAddr.toLowerCase());
57
+ if (!bond)
58
+ return;
59
+ const [billInfo, vesting] = await Promise.all([
60
+ readAptosBillInfo(marketAddr, billId),
61
+ readVestingProgress(marketAddr, billId),
62
+ ]);
63
+ const principalAddr = bond.lpToken.address[aptosKey]?.toLowerCase();
64
+ const payoutAddr = bond.earnToken.address[aptosKey]?.toLowerCase();
65
+ let principalPrice = aptosPrices.find((t) => t.tokenAddress.toLowerCase() === principalAddr)?.price;
66
+ let payoutPrice = aptosPrices.find((t) => t.tokenAddress.toLowerCase() === payoutAddr)?.price;
67
+ // Fallback: individual price-api call (same pattern as fetchBillsUserSolana.ts).
68
+ // TODO(aptos): price-api pending Aptos support. Fallback to hardcoded prices.
69
+ if (principalPrice === undefined && priceApiUrl) {
70
+ try {
71
+ const res = await axios.get(`${priceApiUrl}/realtime/price?token=${bond.lpToken.address[aptosKey]}&chain=${aptosKey}`);
72
+ principalPrice = parseFloat(res.data.price ?? '0');
73
+ }
74
+ catch {
75
+ principalPrice = 1.0;
76
+ }
77
+ }
78
+ if (payoutPrice === undefined && priceApiUrl) {
79
+ try {
80
+ const res = await axios.get(`${priceApiUrl}/realtime/price?token=${bond.earnToken.address[aptosKey]}&chain=${aptosKey}`);
81
+ payoutPrice = parseFloat(res.data.price ?? '0');
82
+ }
83
+ catch {
84
+ payoutPrice = 0.05;
85
+ }
86
+ }
87
+ const payoutTotal = String(billInfo.payout ?? '0');
88
+ const payoutClaimed = String(billInfo.payout_claimed ?? '0');
89
+ const payoutRemaining = (BigInt(payoutTotal) - BigInt(payoutClaimed)).toString();
90
+ const vestingStart = billInfo.vesting_start_timestamp ?? billInfo.last_timestamp ?? '0';
91
+ const lastClaim = billInfo.last_claim_timestamp ?? billInfo.last_timestamp ?? vestingStart;
92
+ // Compute human-readable amounts for the modal display.
93
+ const payoutDecimals = bond.earnToken.decimals[aptosKey] ?? 8;
94
+ const principalDecimals = bond.lpToken.decimals[aptosKey] ?? 8;
95
+ const payoutHuman = parseFloat(payoutTotal) / 10 ** payoutDecimals;
96
+ // Reconstruct deposit from payout and true_price_paid:
97
+ // price = principal_amount * 1e8 / payout_amount → principal = payout * price / 1e8
98
+ const truePricePaid = parseFloat(String(billInfo.true_price_paid ?? '0'));
99
+ const depositAtomic = (parseFloat(payoutTotal) * truePricePaid) / 1e8;
100
+ const depositHuman = depositAtomic / 10 ** principalDecimals;
101
+ const depositUSD = depositHuman * (principalPrice ?? 0);
102
+ const userBill = {
103
+ // `UserBill.address` is used by the SDK's claim flow as the
104
+ // second argument to `bond::claim(market, bill_addr)`. Must be
105
+ // the object address, NOT the scalar bill_id.
106
+ address: billAddr,
107
+ id: billId,
108
+ vestingTerm: String(billInfo.vesting_term ?? '0'),
109
+ payout: payoutRemaining,
110
+ totalPayout: payoutTotal,
111
+ truePricePaid: String(billInfo.true_price_paid ?? '0'),
112
+ lastBlockTimestamp: String(lastClaim),
113
+ vestingStartTimestamp: String(vestingStart),
114
+ pendingRewards: vesting[1], // claimable from vesting_progress tuple
115
+ billNftAddress: bond.billNnftAddress[aptosKey] ?? '',
116
+ payoutClaimed,
117
+ nftData: {
118
+ tokenId: 0,
119
+ billNftId: parseInt(billId),
120
+ processing: false,
121
+ image: APTOS_PLACEHOLDER_BILL_IMAGE,
122
+ // Populate `data` so YourBondsModal can display Deposit/Bond Value.
123
+ // api-v2 won't enrich Aptos bills, so we compute from on-chain data.
124
+ data: {
125
+ dollarValue: depositUSD,
126
+ payout: payoutHuman,
127
+ billContract: marketAddr,
128
+ billNftAddress: bond.billNnftAddress[aptosKey] ?? '',
129
+ billNftId: parseInt(billId),
130
+ blockNumber: 0,
131
+ bondArtCollection: '',
132
+ bondPartner: '',
133
+ bondVersion: bond.version ?? '',
134
+ chainId: aptosKey,
135
+ createTransactionHash: '',
136
+ createdAddressOwner: user,
137
+ createdAt: parseInt(String(vestingStart)),
138
+ deposit: depositHuman,
139
+ expires: parseInt(String(vestingStart)) + parseInt(String(billInfo.vesting_term ?? '0')),
140
+ pairName: `${bond.lpToken.symbol}-${bond.earnToken.symbol}`,
141
+ payoutToken: bond.earnToken.address[aptosKey] ?? '',
142
+ payoutTokenData: {
143
+ address: bond.earnToken.address[aptosKey] ?? '',
144
+ name: bond.earnToken.symbol,
145
+ symbol: bond.earnToken.symbol,
146
+ decimals: bond.earnToken.decimals,
147
+ },
148
+ payoutTokenPrice: (payoutPrice ?? 0).toString(),
149
+ principalToken: bond.lpToken.address[aptosKey] ?? '',
150
+ token0: {
151
+ address: bond.lpToken.address[aptosKey] ?? '',
152
+ symbol: bond.lpToken.symbol,
153
+ name: bond.lpToken.symbol,
154
+ decimals: bond.lpToken.decimals,
155
+ },
156
+ token1: {
157
+ address: bond.earnToken.address[aptosKey] ?? '',
158
+ symbol: bond.earnToken.symbol,
159
+ name: bond.earnToken.symbol,
160
+ decimals: bond.earnToken.decimals,
161
+ },
162
+ type: bond.billType ?? 'reserve',
163
+ vestingPeriodSeconds: parseInt(String(billInfo.vesting_term ?? '0')),
164
+ },
165
+ },
166
+ bond: {
167
+ ...bond,
168
+ payoutTokenPrice: payoutPrice?.toString(),
169
+ principalTokenPrice: principalPrice?.toString(),
170
+ },
171
+ };
172
+ const entry = indexByBondIndex.get(bond.index);
173
+ entry?.userOwnedBills.push(userBill);
174
+ }
175
+ catch (billErr) {
176
+ console.warn(`[Aptos] Failed to read bill ${billId}`, billErr);
177
+ }
178
+ }));
179
+ }
180
+ catch (e) {
181
+ console.warn(`[Aptos] Failed to list user bills for ${user}`, e);
182
+ }
183
+ return result;
184
+ }
185
+
186
+ export { fetchUserOwnedAptosBonds };
187
+ //# sourceMappingURL=fetchBillsUserAptos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetchBillsUserAptos.js","sources":["../../../src/state/bonds/fetchBillsUserAptos.ts"],"sourcesContent":["// =============================================================================\n// fetchUserOwnedAptosBonds — user bills fetcher for the Aptos chain\n// =============================================================================\n//\n// On-chain first: reads user bills directly via Move view functions (no\n// api-v2 dependency). Uses:\n//\n// bond_nft::user_bills(user) → [bill_id, ...]\n// bond_nft::bond_market_by_id(bill_id) → market_addr\n// bond_nft::nft_address(bill_id) → bill_addr\n// bond::bill_info(market, bill_addr) → Bill struct\n// bond_nft::vesting_progress(bill_id) → [total_vested, claimable]\n\nimport { BillsConfig, ChainId } from '@ape.swap/apeswap-lists'\nimport type { UserOwnedBillsData, UserBill } from '../../types/yourbonds'\nimport type { BondsData } from '../../types/bonds'\nimport type { TokenPrices } from '../tokenPrices/useTokenPrices'\nimport { APTOS_PLACEHOLDER_BILL_IMAGE } from '../../constants/aptosConstants'\nimport axios from 'axios'\nimport {\n readAptosBillInfo,\n readBondMarketByBillId,\n readNftAddressByBillId,\n readUserBillIds,\n readVestingProgress,\n} from '../../utils/aptosHelpers'\n\nexport async function fetchUserOwnedAptosBonds(\n user: string | undefined,\n bondData: BillsConfig[],\n tokenPrices: Partial<Record<ChainId, TokenPrices[]>>,\n priceApiUrl?: string,\n): Promise<UserOwnedBillsData[]> {\n if (!user) return []\n\n // Build one `UserOwnedBillsData` per known bond config. We always return\n // the outer shell so downstream code (`getUserBonds` in useUserBonds.ts)\n // can match bills back to their bond config.\n const aptosKey = ChainId.APTOS_MAINNET\n const aptosPrices = tokenPrices?.[aptosKey] ?? []\n\n // Index bonds by lowercased market address for O(1) lookup when matching\n // bill_ids back to their market.\n const bondsByMarket = new Map<string, BillsConfig>()\n for (const bond of bondData) {\n const marketAddr = bond.contractAddress[aptosKey]\n if (marketAddr) bondsByMarket.set(marketAddr.toLowerCase(), bond)\n }\n\n // Seed the result with empty shells so every bond is represented.\n const result: UserOwnedBillsData[] = bondData.map((bond) => ({\n index: bond.index,\n userOwnedBills: [] as UserBill[],\n }))\n const indexByBondIndex = new Map<number, UserOwnedBillsData>()\n for (const entry of result) indexByBondIndex.set(entry.index, entry)\n\n try {\n const billIds = await readUserBillIds(user)\n if (billIds.length === 0) return result\n\n // For each bill the user owns, resolve its market, object address, state\n // and vesting progress in parallel. Bills whose market is not in our\n // bondData are silently skipped (they belong to a market the SDK isn't\n // configured to display).\n await Promise.all(\n billIds.map(async (billId) => {\n try {\n const [marketAddr, billAddr] = await Promise.all([\n readBondMarketByBillId(billId),\n readNftAddressByBillId(billId),\n ])\n const bond = bondsByMarket.get(marketAddr.toLowerCase())\n if (!bond) return\n\n const [billInfo, vesting] = await Promise.all([\n readAptosBillInfo(marketAddr, billId),\n readVestingProgress(marketAddr, billId),\n ])\n\n const principalAddr = bond.lpToken.address[aptosKey]?.toLowerCase()\n const payoutAddr = bond.earnToken.address[aptosKey]?.toLowerCase()\n let principalPrice = aptosPrices.find((t) => t.tokenAddress.toLowerCase() === principalAddr)?.price\n let payoutPrice = aptosPrices.find((t) => t.tokenAddress.toLowerCase() === payoutAddr)?.price\n\n // Fallback: individual price-api call (same pattern as fetchBillsUserSolana.ts).\n // TODO(aptos): price-api pending Aptos support. Fallback to hardcoded prices.\n if (principalPrice === undefined && priceApiUrl) {\n try {\n const res = await axios.get(\n `${priceApiUrl}/realtime/price?token=${bond.lpToken.address[aptosKey]}&chain=${aptosKey}`,\n )\n principalPrice = parseFloat(res.data.price ?? '0')\n } catch {\n principalPrice = 1.0\n }\n }\n if (payoutPrice === undefined && priceApiUrl) {\n try {\n const res = await axios.get(\n `${priceApiUrl}/realtime/price?token=${bond.earnToken.address[aptosKey]}&chain=${aptosKey}`,\n )\n payoutPrice = parseFloat(res.data.price ?? '0')\n } catch {\n payoutPrice = 0.05\n }\n }\n\n const payoutTotal = String(billInfo.payout ?? '0')\n const payoutClaimed = String(billInfo.payout_claimed ?? '0')\n const payoutRemaining = (BigInt(payoutTotal) - BigInt(payoutClaimed)).toString()\n const vestingStart = billInfo.vesting_start_timestamp ?? billInfo.last_timestamp ?? '0'\n const lastClaim = billInfo.last_claim_timestamp ?? billInfo.last_timestamp ?? vestingStart\n\n // Compute human-readable amounts for the modal display.\n const payoutDecimals = bond.earnToken.decimals[aptosKey] ?? 8\n const principalDecimals = bond.lpToken.decimals[aptosKey] ?? 8\n const payoutHuman = parseFloat(payoutTotal) / 10 ** payoutDecimals\n // Reconstruct deposit from payout and true_price_paid:\n // price = principal_amount * 1e8 / payout_amount → principal = payout * price / 1e8\n const truePricePaid = parseFloat(String(billInfo.true_price_paid ?? '0'))\n const depositAtomic = (parseFloat(payoutTotal) * truePricePaid) / 1e8\n const depositHuman = depositAtomic / 10 ** principalDecimals\n const depositUSD = depositHuman * (principalPrice ?? 0)\n\n const userBill: UserBill = {\n // `UserBill.address` is used by the SDK's claim flow as the\n // second argument to `bond::claim(market, bill_addr)`. Must be\n // the object address, NOT the scalar bill_id.\n address: billAddr,\n id: billId,\n vestingTerm: String(billInfo.vesting_term ?? '0'),\n payout: payoutRemaining,\n totalPayout: payoutTotal,\n truePricePaid: String(billInfo.true_price_paid ?? '0'),\n lastBlockTimestamp: String(lastClaim),\n vestingStartTimestamp: String(vestingStart),\n pendingRewards: vesting[1], // claimable from vesting_progress tuple\n billNftAddress: bond.billNnftAddress[aptosKey] ?? '',\n payoutClaimed,\n nftData: {\n tokenId: 0,\n billNftId: parseInt(billId),\n processing: false,\n image: APTOS_PLACEHOLDER_BILL_IMAGE,\n // Populate `data` so YourBondsModal can display Deposit/Bond Value.\n // api-v2 won't enrich Aptos bills, so we compute from on-chain data.\n data: {\n dollarValue: depositUSD,\n payout: payoutHuman,\n billContract: marketAddr,\n billNftAddress: bond.billNnftAddress[aptosKey] ?? '',\n billNftId: parseInt(billId),\n blockNumber: 0,\n bondArtCollection: '',\n bondPartner: '',\n bondVersion: bond.version ?? '',\n chainId: aptosKey,\n createTransactionHash: '',\n createdAddressOwner: user,\n createdAt: parseInt(String(vestingStart)),\n deposit: depositHuman,\n expires: parseInt(String(vestingStart)) + parseInt(String(billInfo.vesting_term ?? '0')),\n pairName: `${bond.lpToken.symbol}-${bond.earnToken.symbol}`,\n payoutToken: bond.earnToken.address[aptosKey] ?? '',\n payoutTokenData: {\n address: bond.earnToken.address[aptosKey] ?? '',\n name: bond.earnToken.symbol,\n symbol: bond.earnToken.symbol,\n decimals: bond.earnToken.decimals,\n },\n payoutTokenPrice: (payoutPrice ?? 0).toString(),\n principalToken: bond.lpToken.address[aptosKey] ?? '',\n token0: {\n address: bond.lpToken.address[aptosKey] ?? '',\n symbol: bond.lpToken.symbol,\n name: bond.lpToken.symbol,\n decimals: bond.lpToken.decimals,\n },\n token1: {\n address: bond.earnToken.address[aptosKey] ?? '',\n symbol: bond.earnToken.symbol,\n name: bond.earnToken.symbol,\n decimals: bond.earnToken.decimals,\n },\n type: bond.billType ?? 'reserve',\n vestingPeriodSeconds: parseInt(String(billInfo.vesting_term ?? '0')),\n },\n },\n bond: {\n ...bond,\n payoutTokenPrice: payoutPrice?.toString(),\n principalTokenPrice: principalPrice?.toString(),\n } as BondsData,\n }\n\n const entry = indexByBondIndex.get(bond.index)\n entry?.userOwnedBills.push(userBill)\n } catch (billErr) {\n console.warn(`[Aptos] Failed to read bill ${billId}`, billErr)\n }\n }),\n )\n } catch (e) {\n console.warn(`[Aptos] Failed to list user bills for ${user}`, e)\n }\n\n return result\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { BillsConfig, ChainId } from '@ape.swap/apeswap-lists';
2
+ import type { UserOwnedBillsData } from '../../types/yourbonds';
3
+ import type { TokenPrices } from '../tokenPrices/useTokenPrices';
4
+ export declare function fetchUserOwnedSuiBonds(user: string | undefined, bondData: BillsConfig[], tokenPrices: Partial<Record<ChainId, TokenPrices[]>>, priceApiUrl?: string): Promise<UserOwnedBillsData[]>;
@@ -0,0 +1,287 @@
1
+ import { ChainId } from '@ape.swap/apeswap-lists';
2
+ import { SUI_PLACEHOLDER_BILL_IMAGE, SUI_PACKAGE_ID } from '../../constants/suiConstants.js';
3
+ import { getSuiClient } from '../../utils/suiHelpers.js';
4
+ import axios from 'axios';
5
+
6
+ // =============================================================================
7
+ // fetchUserOwnedSuiBonds — user bills fetcher for the Sui chain
8
+ // =============================================================================
9
+ //
10
+ // On-chain first: reads user bills directly from Sui objects (no api-v2
11
+ // dependency). Uses:
12
+ //
13
+ // getOwnedObjects(user, BondNFT filter) → [BondNFT objects]
14
+ // Each BondNFT has fields: bill_id, bond_market, uri
15
+ // getDynamicFieldObject(market.bills, bill_id) → Bill struct
16
+ // Bill fields: payout, payout_claimed, vesting_term, vesting_start_timestamp,
17
+ // last_claim_timestamp, true_price_paid
18
+ /**
19
+ * Fetch all BondNFT objects owned by a user address.
20
+ * Returns the parsed content fields for each NFT.
21
+ */
22
+ async function fetchUserBondNfts(userAddress) {
23
+ const client = getSuiClient();
24
+ const structType = `${SUI_PACKAGE_ID}::bond_nft::BondNFT`;
25
+ const results = [];
26
+ let cursor = undefined;
27
+ let hasNextPage = true;
28
+ while (hasNextPage) {
29
+ const response = await client.getOwnedObjects({
30
+ owner: userAddress,
31
+ filter: { StructType: structType },
32
+ options: { showContent: true },
33
+ cursor: cursor ?? undefined,
34
+ });
35
+ for (const item of response.data) {
36
+ if (!item.data?.content || item.data.content.dataType !== 'moveObject')
37
+ continue;
38
+ const fields = item.data.content.fields;
39
+ results.push({ objectId: item.data.objectId, fields });
40
+ }
41
+ hasNextPage = response.hasNextPage;
42
+ cursor = response.nextCursor;
43
+ }
44
+ return results;
45
+ }
46
+ /**
47
+ * Read a single Bill from a BondMarket's `bills` Table by bill_id.
48
+ *
49
+ * The BondMarket is a shared object whose `bills` field is a `Table<u64, Bill>`.
50
+ * Sui stores Table entries as dynamic fields on the Table's UID. We first read
51
+ * the BondMarket object to get the Table's object ID, then query the dynamic
52
+ * field for the specific bill_id.
53
+ */
54
+ async function readBillFromMarket(marketObjectId, billId) {
55
+ const client = getSuiClient();
56
+ // Step 1: Read the BondMarket object to find the `bills` Table object ID.
57
+ // The `bills` field in a Move struct with `Table<u64, Bill>` is stored as an
58
+ // object ID in the parent object's fields.
59
+ const marketObj = await client.getObject({
60
+ id: marketObjectId,
61
+ options: { showContent: true },
62
+ });
63
+ if (!marketObj.data?.content || marketObj.data.content.dataType !== 'moveObject') {
64
+ throw new Error(`[Sui] BondMarket ${marketObjectId} not found or not a Move object`);
65
+ }
66
+ const marketFields = marketObj.data.content.fields;
67
+ // Table fields in Sui are serialised as { id: { id: "0x..." }, size: N }
68
+ const billsTableId = marketFields?.bills?.fields?.id?.id ?? marketFields?.bills?.id?.id;
69
+ if (!billsTableId) {
70
+ throw new Error(`[Sui] Could not extract bills table ID from BondMarket ${marketObjectId}`);
71
+ }
72
+ // Step 2: Read the dynamic field for this bill_id from the Table.
73
+ const billObj = await client.getDynamicFieldObject({
74
+ parentId: billsTableId,
75
+ name: { type: 'u64', value: billId },
76
+ });
77
+ if (!billObj.data?.content || billObj.data.content.dataType !== 'moveObject') {
78
+ throw new Error(`[Sui] Bill ${billId} not found in market ${marketObjectId}`);
79
+ }
80
+ // The dynamic field value is nested under `fields.value` (or `fields.value.fields`
81
+ // depending on serialisation depth).
82
+ const dfFields = billObj.data.content.fields;
83
+ const billValue = dfFields?.value?.fields ?? dfFields?.value ?? dfFields;
84
+ // Extract cliff period from the market's vesting_config
85
+ const vestingConfig = marketFields?.vesting_config;
86
+ const cliffPeriod = vestingConfig?.variant === 'CliffLinear' ? Number(vestingConfig?.fields?.cliff_period ?? 0) : 0;
87
+ return { ...billValue, cliffPeriod };
88
+ }
89
+ // ---------------------------------------------------------------------------
90
+ // Main export
91
+ // ---------------------------------------------------------------------------
92
+ async function fetchUserOwnedSuiBonds(user, bondData, tokenPrices, priceApiUrl) {
93
+ if (!user)
94
+ return [];
95
+ // Build one `UserOwnedBillsData` per known bond config. We always return
96
+ // the outer shell so downstream code (`getUserBonds` in useUserBonds.ts)
97
+ // can match bills back to their bond config.
98
+ const suiKey = ChainId.SUI_MAINNET;
99
+ const suiPrices = tokenPrices?.[suiKey] ?? [];
100
+ // Index bonds by lowercased market address for O(1) lookup when matching
101
+ // NFTs back to their market.
102
+ const bondsByMarket = new Map();
103
+ for (const bond of bondData) {
104
+ const marketAddr = bond.contractAddress[suiKey];
105
+ if (marketAddr)
106
+ bondsByMarket.set(marketAddr.toLowerCase(), bond);
107
+ }
108
+ // Seed the result with empty shells so every bond is represented.
109
+ const result = bondData.map((bond) => ({
110
+ index: bond.index,
111
+ userOwnedBills: [],
112
+ }));
113
+ const indexByBondIndex = new Map();
114
+ for (const entry of result)
115
+ indexByBondIndex.set(entry.index, entry);
116
+ try {
117
+ const nfts = await fetchUserBondNfts(user);
118
+ if (nfts.length === 0)
119
+ return result;
120
+ // For each BondNFT the user owns, resolve its market, read the bill data,
121
+ // and compute vesting progress. NFTs whose market is not in our bondData
122
+ // are silently skipped (they belong to a market the SDK isn't configured
123
+ // to display).
124
+ await Promise.all(nfts.map(async (nft) => {
125
+ try {
126
+ const { fields } = nft;
127
+ const billId = String(fields.bill_id);
128
+ const marketAddr = fields.bond_market;
129
+ const bond = bondsByMarket.get(marketAddr.toLowerCase());
130
+ if (!bond)
131
+ return;
132
+ const billInfo = await readBillFromMarket(marketAddr, billId);
133
+ const principalAddr = bond.lpToken.address[suiKey]?.toLowerCase();
134
+ const payoutAddr = bond.earnToken.address[suiKey]?.toLowerCase();
135
+ let principalPrice = suiPrices.find((t) => t.tokenAddress.toLowerCase() === principalAddr)?.price;
136
+ let payoutPrice = suiPrices.find((t) => t.tokenAddress.toLowerCase() === payoutAddr)?.price;
137
+ // Fallback: individual price-api call (same pattern as fetchBillsUserAptos.ts).
138
+ // TODO(sui): price-api pending Sui support. Fallback to hardcoded prices.
139
+ if (principalPrice === undefined && priceApiUrl) {
140
+ try {
141
+ const res = await axios.get(`${priceApiUrl}/realtime/price?token=${bond.lpToken.address[suiKey]}&chain=${suiKey}`);
142
+ principalPrice = parseFloat(res.data.price ?? '0');
143
+ }
144
+ catch {
145
+ principalPrice = 1.0;
146
+ }
147
+ }
148
+ if (payoutPrice === undefined && priceApiUrl) {
149
+ try {
150
+ const res = await axios.get(`${priceApiUrl}/realtime/price?token=${bond.earnToken.address[suiKey]}&chain=${suiKey}`);
151
+ payoutPrice = parseFloat(res.data.price ?? '0');
152
+ }
153
+ catch {
154
+ payoutPrice = 0.05;
155
+ }
156
+ }
157
+ const payoutTotal = String(billInfo.payout ?? '0');
158
+ const payoutClaimed = String(billInfo.payout_claimed ?? '0');
159
+ const payoutRemaining = (BigInt(payoutTotal) - BigInt(payoutClaimed)).toString();
160
+ const vestingStart = String(billInfo.vesting_start_timestamp ?? '0');
161
+ const lastClaim = String(billInfo.last_claim_timestamp ?? vestingStart);
162
+ // Compute vesting progress client-side using the same curve as the contract.
163
+ // Supports both Linear and CliffLinear vesting configurations.
164
+ const nowSeconds = Math.floor(Date.now() / 1000);
165
+ const vestingTerm = parseInt(String(billInfo.vesting_term ?? '0'));
166
+ const vestingStartNum = parseInt(vestingStart);
167
+ const cliffPeriod = billInfo.cliffPeriod ?? 0;
168
+ const elapsed = Math.max(0, nowSeconds - vestingStartNum);
169
+ let totalVested;
170
+ if (cliffPeriod > 0) {
171
+ // CliffLinear: nothing vests until cliff passes, then linear over remaining term
172
+ if (elapsed < cliffPeriod) {
173
+ totalVested = 0;
174
+ }
175
+ else if (elapsed >= vestingTerm) {
176
+ totalVested = parseInt(payoutTotal);
177
+ }
178
+ else {
179
+ const elapsedAfterCliff = elapsed - cliffPeriod;
180
+ const vestingAfterCliff = vestingTerm - cliffPeriod;
181
+ totalVested =
182
+ vestingAfterCliff > 0
183
+ ? Math.floor((parseInt(payoutTotal) * elapsedAfterCliff) / vestingAfterCliff)
184
+ : parseInt(payoutTotal);
185
+ }
186
+ }
187
+ else {
188
+ // Linear: standard proportional vesting
189
+ const vestedFraction = vestingTerm > 0 ? Math.min(1, elapsed / vestingTerm) : 1;
190
+ totalVested = Math.floor(parseFloat(payoutTotal) * vestedFraction);
191
+ }
192
+ const claimable = Math.max(0, totalVested - parseInt(payoutClaimed));
193
+ // Compute human-readable amounts for the modal display.
194
+ const payoutDecimals = bond.earnToken.decimals[suiKey] ?? 9;
195
+ const principalDecimals = bond.lpToken.decimals[suiKey] ?? 9;
196
+ const payoutHuman = parseFloat(payoutTotal) / 10 ** payoutDecimals;
197
+ // Reconstruct deposit from payout and true_price_paid:
198
+ // price = principal_amount * 1e8 / payout_amount -> principal = payout * price / 1e8
199
+ const truePricePaid = parseFloat(String(billInfo.true_price_paid ?? '0'));
200
+ const depositAtomic = (parseFloat(payoutTotal) * truePricePaid) / 1e8;
201
+ const depositHuman = depositAtomic / 10 ** principalDecimals;
202
+ const depositUSD = depositHuman * (principalPrice ?? 0);
203
+ const userBill = {
204
+ // `UserBill.address` is used by the SDK's claim flow. On Sui, this
205
+ // is the BondNFT object ID that the user passes to `bond::claim`.
206
+ address: nft.objectId,
207
+ id: billId,
208
+ vestingTerm: String(billInfo.vesting_term ?? '0'),
209
+ payout: payoutRemaining,
210
+ totalPayout: payoutTotal,
211
+ truePricePaid: String(billInfo.true_price_paid ?? '0'),
212
+ lastBlockTimestamp: String(lastClaim),
213
+ vestingStartTimestamp: String(vestingStart),
214
+ pendingRewards: String(claimable),
215
+ billNftAddress: bond.billNnftAddress[suiKey] ?? '',
216
+ payoutClaimed,
217
+ nftData: {
218
+ tokenId: 0,
219
+ billNftId: parseInt(billId),
220
+ processing: false,
221
+ image: SUI_PLACEHOLDER_BILL_IMAGE,
222
+ // Populate `data` so YourBondsModal can display Deposit/Bond Value.
223
+ // api-v2 won't enrich Sui bills, so we compute from on-chain data.
224
+ data: {
225
+ dollarValue: depositUSD,
226
+ payout: payoutHuman,
227
+ billContract: marketAddr,
228
+ billNftAddress: bond.billNnftAddress[suiKey] ?? '',
229
+ billNftId: parseInt(billId),
230
+ blockNumber: 0,
231
+ bondArtCollection: '',
232
+ bondPartner: '',
233
+ bondVersion: bond.version ?? '',
234
+ chainId: suiKey,
235
+ createTransactionHash: '',
236
+ createdAddressOwner: user,
237
+ createdAt: parseInt(String(vestingStart)),
238
+ deposit: depositHuman,
239
+ expires: parseInt(String(vestingStart)) + parseInt(String(billInfo.vesting_term ?? '0')),
240
+ pairName: `${bond.lpToken.symbol}-${bond.earnToken.symbol}`,
241
+ payoutToken: bond.earnToken.address[suiKey] ?? '',
242
+ payoutTokenData: {
243
+ address: bond.earnToken.address[suiKey] ?? '',
244
+ name: bond.earnToken.symbol,
245
+ symbol: bond.earnToken.symbol,
246
+ decimals: bond.earnToken.decimals,
247
+ },
248
+ payoutTokenPrice: (payoutPrice ?? 0).toString(),
249
+ principalToken: bond.lpToken.address[suiKey] ?? '',
250
+ token0: {
251
+ address: bond.lpToken.address[suiKey] ?? '',
252
+ symbol: bond.lpToken.symbol,
253
+ name: bond.lpToken.symbol,
254
+ decimals: bond.lpToken.decimals,
255
+ },
256
+ token1: {
257
+ address: bond.earnToken.address[suiKey] ?? '',
258
+ symbol: bond.earnToken.symbol,
259
+ name: bond.earnToken.symbol,
260
+ decimals: bond.earnToken.decimals,
261
+ },
262
+ type: bond.billType ?? 'reserve',
263
+ vestingPeriodSeconds: parseInt(String(billInfo.vesting_term ?? '0')),
264
+ },
265
+ },
266
+ bond: {
267
+ ...bond,
268
+ payoutTokenPrice: payoutPrice?.toString(),
269
+ principalTokenPrice: principalPrice?.toString(),
270
+ },
271
+ };
272
+ const entry = indexByBondIndex.get(bond.index);
273
+ entry?.userOwnedBills.push(userBill);
274
+ }
275
+ catch (billErr) {
276
+ console.warn(`[Sui] Failed to read bill from NFT ${nft.objectId}`, billErr);
277
+ }
278
+ }));
279
+ }
280
+ catch (e) {
281
+ console.warn(`[Sui] Failed to list user bills for ${user}`, e);
282
+ }
283
+ return result;
284
+ }
285
+
286
+ export { fetchUserOwnedSuiBonds };
287
+ //# sourceMappingURL=fetchBillsUserSui.js.map