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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +2 -0
  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,152 @@
1
+ /**
2
+ * BondTerms — mirror of `apebond::bond::BondTerms`.
3
+ * `control_variable` is the BCV scaled by `bond::PERCENTAGE_BASE` (1e6).
4
+ * `vesting_term` and timestamps are in seconds.
5
+ */
6
+ export interface AptosBondTerms {
7
+ control_variable: string;
8
+ vesting_term: string;
9
+ minimum_price: string;
10
+ max_payout: string;
11
+ max_debt: string;
12
+ max_total_payout: string;
13
+ initial_debt: string;
14
+ }
15
+ /**
16
+ * AptosBondMarket — subset of `apebond::bond::BondMarket` that we actually
17
+ * read from the SDK. `extend_ref`, `operators`, `redeemer_approved` and the
18
+ * full `bills` map are intentionally omitted to keep the TS shape lean.
19
+ */
20
+ export interface AptosBondMarket {
21
+ payout_token: {
22
+ inner: string;
23
+ };
24
+ principal_token: {
25
+ inner: string;
26
+ };
27
+ treasury: {
28
+ inner: string;
29
+ };
30
+ fee_in_principal_recipient: string;
31
+ fee_in_payout_recipient: string;
32
+ terms: AptosBondTerms;
33
+ fee_in_principal: string;
34
+ fee_in_payout: string;
35
+ total_principal_billed: string;
36
+ total_payout_given: string;
37
+ payout_token_initial_supply: string;
38
+ total_debt: string;
39
+ last_decay: string;
40
+ last_bcv_update_timestamp: string;
41
+ min_bcv_update_interval: string;
42
+ paused: boolean;
43
+ emergency_paused: boolean;
44
+ name: string;
45
+ }
46
+ /**
47
+ * Derived pricing view — the values that the `bond_pricing` view function
48
+ * returns in a single shot. Kept as a separate interface because some
49
+ * consumers only care about pricing and we do not want to force them to read
50
+ * the whole market resource.
51
+ */
52
+ export interface AptosBondPricing {
53
+ bond_price: string;
54
+ true_bond_price: string;
55
+ debt_ratio: string;
56
+ debt_decay: string;
57
+ current_debt: string;
58
+ }
59
+ /**
60
+ * Bill — mirror of `apebond::bond::Bill`. One per user position.
61
+ */
62
+ export interface AptosBill {
63
+ payout: string;
64
+ payout_claimed: string;
65
+ vesting_term: string;
66
+ vesting_start_timestamp: string;
67
+ last_claim_timestamp: string;
68
+ true_price_paid: string;
69
+ }
70
+ /**
71
+ * Arguments forwarded to `apebond::bond::deposit`. Numeric values are always
72
+ * stringified BigInts to keep compatibility with the Aptos TS SDK which
73
+ * serialises BCS arguments from strings.
74
+ */
75
+ export interface AptosDepositPayload {
76
+ market: string;
77
+ amount: string;
78
+ max_price: string;
79
+ depositor: string;
80
+ }
81
+ /**
82
+ * Arguments forwarded to `apebond::bond::claim(market, bill_id: u64)`.
83
+ */
84
+ export interface AptosClaimPayload {
85
+ market: string;
86
+ bill_id: string;
87
+ }
88
+ /**
89
+ * Tuple shape returned by `apebond::bond::market_info(market)` — 27 elements.
90
+ *
91
+ * Reference: apebond-move-playground/app/bond-market-info/page.tsx reads
92
+ * every index individually and labels it the same way.
93
+ *
94
+ * All `u64` / `u128` fields come back as strings to preserve precision.
95
+ * `true_bill_price` (index 17) is scaled by `PRICE_DECIMALS = 1e8`.
96
+ */
97
+ export type AptosMarketInfoTuple = readonly [
98
+ name: string,
99
+ owner: string,
100
+ paused: boolean,
101
+ emergencyPaused: boolean,
102
+ totalPrincipalBilled: string,
103
+ totalPayoutGiven: string,
104
+ currentDebt: string,
105
+ treasury: string,
106
+ treasuryOwner: string,
107
+ treasuryPayoutAddress: string,
108
+ payoutToken: string,
109
+ principalToken: string,
110
+ billNftCollection: string,
111
+ feeInPrincipal: string,
112
+ feeInPayout: string,
113
+ feeInPrincipalRecipient: string,
114
+ feeInPayoutRecipient: string,
115
+ trueBillPrice: string,
116
+ controlVariable: string,
117
+ vestingTerm: string,
118
+ minimumPrice: string,
119
+ maxPayout: string,
120
+ maxDebt: string,
121
+ maxTotalPayout: string,
122
+ vestingType: string,
123
+ cliffPeriod: string,
124
+ currentTimestamp: string
125
+ ];
126
+ /**
127
+ * Tuple shape returned by `apebond::bond_nft::vesting_progress(bill_id)`.
128
+ * `[total_vested, claimable]` — both u64, both scaled by the payout token's
129
+ * decimals.
130
+ */
131
+ export type AptosVestingProgressTuple = readonly [totalVested: string, claimable: string];
132
+ /**
133
+ * Result of `apebond::bond::bill_info(market, bill_addr)`. The playground
134
+ * documents the fields as:
135
+ * "Bill struct contains: payout, payout_claimed, vesting_term,
136
+ * last_timestamp, true_price_paid"
137
+ * We also include `vesting_start_timestamp` which exists in the underlying
138
+ * Move struct (`apebond-move/sources/bond.move::Bill`).
139
+ *
140
+ * TODO(APTOS): verify the exact field names against the deployed
141
+ * contract. The playground serialises the struct via `JSON.stringify(bill[0])`
142
+ * so the Move field names are preserved verbatim.
143
+ */
144
+ export interface AptosBillInfo {
145
+ payout: string;
146
+ payout_claimed: string;
147
+ vesting_term: string;
148
+ vesting_start_timestamp?: string;
149
+ last_claim_timestamp?: string;
150
+ last_timestamp?: string;
151
+ true_price_paid: string;
152
+ }
@@ -57,9 +57,7 @@ export interface UserBillNftData {
57
57
  address: string;
58
58
  name: string;
59
59
  symbol: string;
60
- decimals: {
61
- [chainId: number]: number;
62
- };
60
+ decimals: Partial<Record<ChainId, number | null>>;
63
61
  };
64
62
  payoutTokenPrice: string;
65
63
  principalToken: string;
@@ -67,17 +65,13 @@ export interface UserBillNftData {
67
65
  address: string;
68
66
  symbol: string;
69
67
  name: string;
70
- decimals: {
71
- [chainId: number]: number;
72
- };
68
+ decimals: Partial<Record<ChainId, number | null>>;
73
69
  };
74
70
  token1: {
75
71
  address: string;
76
72
  symbol: string;
77
73
  name: string;
78
- decimals: {
79
- [chainId: number]: number;
80
- };
74
+ decimals: Partial<Record<ChainId, number | null>>;
81
75
  };
82
76
  type: string;
83
77
  vestingPeriodSeconds: number;
@@ -0,0 +1,80 @@
1
+ import { Aptos } from '@aptos-labs/ts-sdk';
2
+ import type { AptosBillInfo, AptosClaimPayload, AptosDepositPayload, AptosMarketInfoTuple, AptosVestingProgressTuple } from '../types/aptosBonds';
3
+ export declare const getAptosClient: () => Aptos;
4
+ export declare const safeExtractAddress: (input: unknown) => string | undefined;
5
+ export declare const toAtomicUnits: (amount: string | number, decimals: number) => string;
6
+ export declare const buildDepositPayload: (args: AptosDepositPayload) => {
7
+ function: `${string}::${string}::${string}`;
8
+ typeArguments: string[];
9
+ functionArguments: (string | number)[];
10
+ };
11
+ export declare const buildClaimPayload: (args: AptosClaimPayload) => {
12
+ function: `${string}::${string}::${string}`;
13
+ typeArguments: string[];
14
+ functionArguments: (string | number)[];
15
+ };
16
+ interface AptosTxnWithEvents {
17
+ events?: Array<{
18
+ type: string;
19
+ data: Record<string, unknown>;
20
+ }>;
21
+ }
22
+ export declare const extractEventData: <T = Record<string, unknown>>(txn: AptosTxnWithEvents, eventSuffix: string) => T | undefined;
23
+ /**
24
+ * `bond::DepositEvent` — emitted by the deposit entry function.
25
+ * Contains bill_id, bill_address, deposit_amount, payout_amount, price.
26
+ */
27
+ export declare const extractDepositEvent: (txn: AptosTxnWithEvents) => {
28
+ bill_id: string;
29
+ bill_address: string;
30
+ market: string;
31
+ deposit_amount: string;
32
+ payout_amount: string;
33
+ price: string;
34
+ depositor: string;
35
+ recipient: string;
36
+ } | undefined;
37
+ /**
38
+ * Extract bill_id from transaction events. Checks both `BillMinted` (from bond_nft)
39
+ * and `DepositEvent` (from bond) since the contract emits both.
40
+ */
41
+ export declare const extractBillMinted: (txn: AptosTxnWithEvents) => {
42
+ bill_id: string;
43
+ owner: string;
44
+ } | undefined;
45
+ export declare const aptosIndexerFetch: <T = unknown>(url: string, query: string, variables?: Record<string, unknown>) => Promise<T>;
46
+ /**
47
+ * `bond::market_info(market)` — returns the 27-element market info tuple.
48
+ */
49
+ export declare const readAptosMarketInfo: (marketAddress: string) => Promise<AptosMarketInfoTuple>;
50
+ /**
51
+ * `bond::bill_info(market, bill_id)` — returns the Bill struct for a
52
+ * specific bill. The contract takes `bill_id: u64` (NOT the object address).
53
+ * Uses REST directly to avoid SDK remoteAbi serialisation bug with u64 args.
54
+ */
55
+ export declare const readAptosBillInfo: (marketAddress: string, billId: string) => Promise<AptosBillInfo>;
56
+ /**
57
+ * `bond_nft::user_bills(user)` — returns all bill_ids owned by the user
58
+ * across every deployed market. The view returns `[bill_ids]` (the inner
59
+ * array is at index 0), so we unwrap it here.
60
+ */
61
+ export declare const readUserBillIds: (user: string) => Promise<string[]>;
62
+ /**
63
+ * `bond::vesting_progress(market, bill_id)` — returns `[vested_amount, claimable_amount]`.
64
+ * Note: this is in `bond` module (not `bond_nft`), and takes the market as first argument.
65
+ * Uses REST directly to avoid SDK remoteAbi serialisation bug with u64 args.
66
+ */
67
+ export declare const readVestingProgress: (marketAddress: string, billId: string) => Promise<AptosVestingProgressTuple>;
68
+ /**
69
+ * `bond_nft::bond_market_by_id(bill_id)` — which market owns this bill.
70
+ * Uses REST directly — SDK's aptos.view() mis-serialises u64→address functions.
71
+ */
72
+ export declare const readBondMarketByBillId: (billId: string) => Promise<string>;
73
+ /**
74
+ * `bond_nft::nft_address(bill_id)` — resolve the scalar bill_id to the
75
+ * on-chain NFT object address (aka `bill_addr`). Needed to then call
76
+ * `bond::bill_info(market, bill_addr)` or `bond::claim(market, bill_addr)`.
77
+ * Uses REST directly — SDK's aptos.view() mis-serialises u64→address functions.
78
+ */
79
+ export declare const readNftAddressByBillId: (billId: string) => Promise<string>;
80
+ export {};
@@ -0,0 +1,202 @@
1
+ import { AptosConfig, Aptos } from '@aptos-labs/ts-sdk';
2
+ import 'bignumber.js';
3
+ import { APTOS_VIEW_USER_BILLS, APTOS_NETWORK, APTOS_FULLNODE_URL, APTOS_VIEW_BOND_MARKET_BY_ID, APTOS_VIEW_NFT_ADDRESS, APTOS_VIEW_BILL_INFO, APTOS_VIEW_VESTING_PROGRESS, getRandomAptosApiKey, APTOS_VIEW_MARKET_INFO } from '../constants/aptosConstants.js';
4
+
5
+ // ---------------------------------------------------------------------------
6
+ // Aptos client — lazy singleton
7
+ // ---------------------------------------------------------------------------
8
+ // We keep one client per (network, api key) pair. The API key is picked with
9
+ // `getRandomAptosApiKey()` on first call, so different sessions hit a
10
+ // different key (very simple load balancing). If the pool is empty we fall
11
+ // back to unauthenticated requests.
12
+ let _aptosClient;
13
+ const getAptosClient = () => {
14
+ if (_aptosClient)
15
+ return _aptosClient;
16
+ const apiKey = getRandomAptosApiKey();
17
+ // The Aptos ts-sdk exposes `API_KEY` directly on `clientConfig`; it adds
18
+ // the `Authorization: Bearer <key>` header internally. This is the
19
+ // idiomatic way to authenticate — no manual header wiring needed.
20
+ const config = new AptosConfig({
21
+ network: APTOS_NETWORK,
22
+ ...(apiKey && { clientConfig: { API_KEY: apiKey } }),
23
+ });
24
+ _aptosClient = new Aptos(config);
25
+ return _aptosClient;
26
+ };
27
+ // ---------------------------------------------------------------------------
28
+ // Address normalisation
29
+ // ---------------------------------------------------------------------------
30
+ // Aptos wallet adapters can surface account addresses in several shapes:
31
+ // plain string, `{ data: Uint8Array }`, `Uint8Array`, or an `AccountAddress`
32
+ // instance. This helper returns a canonical `0x`-prefixed hex string, or
33
+ // `undefined` if the input cannot be decoded. We keep the interface loose so
34
+ // callers can pass whatever the SDK hands them.
35
+ const safeExtractAddress = (input) => {
36
+ if (input == null)
37
+ return undefined;
38
+ // Already a string
39
+ if (typeof input === 'string') {
40
+ return input.startsWith('0x') ? input : `0x${input}`;
41
+ }
42
+ // AccountAddress instance (has `toString()` that returns `0x...`)
43
+ if (typeof input === 'object' && typeof input.toString === 'function') {
44
+ const asObject = input;
45
+ // Prefer `.data` if it looks like a byte array — `.toString()` on
46
+ // AccountAddress already returns the canonical hex, but some wallets
47
+ // return `{ data: Uint8Array }` without the method.
48
+ if (asObject.data instanceof Uint8Array) {
49
+ return bytesToHex(asObject.data);
50
+ }
51
+ if (Array.isArray(asObject.data)) {
52
+ return bytesToHex(new Uint8Array(asObject.data));
53
+ }
54
+ const stringified = asObject.toString();
55
+ if (stringified.startsWith('0x'))
56
+ return stringified;
57
+ }
58
+ // Raw Uint8Array
59
+ if (input instanceof Uint8Array) {
60
+ return bytesToHex(input);
61
+ }
62
+ // Raw number[]
63
+ if (Array.isArray(input)) {
64
+ return bytesToHex(new Uint8Array(input));
65
+ }
66
+ return undefined;
67
+ };
68
+ const bytesToHex = (bytes) => {
69
+ let out = '0x';
70
+ for (let i = 0; i < bytes.length; i++) {
71
+ out += bytes[i].toString(16).padStart(2, '0');
72
+ }
73
+ return out;
74
+ };
75
+ const extractEventData = (txn, eventSuffix) => {
76
+ const event = txn?.events?.find((e) => e.type.includes(eventSuffix));
77
+ return event?.data;
78
+ };
79
+ /**
80
+ * `bond::DepositEvent` — emitted by the deposit entry function.
81
+ * Contains bill_id, bill_address, deposit_amount, payout_amount, price.
82
+ */
83
+ const extractDepositEvent = (txn) => extractEventData(txn, '::DepositEvent');
84
+ /**
85
+ * Extract bill_id from transaction events. Checks both `BillMinted` (from bond_nft)
86
+ * and `DepositEvent` (from bond) since the contract emits both.
87
+ */
88
+ const extractBillMinted = (txn) => {
89
+ // Try BillMinted event first (emitted by bond_nft module)
90
+ const billMinted = extractEventData(txn, '::BillMinted');
91
+ if (billMinted)
92
+ return billMinted;
93
+ // Fall back to DepositEvent (emitted by bond module)
94
+ const deposit = extractDepositEvent(txn);
95
+ if (!deposit)
96
+ return undefined;
97
+ return { bill_id: deposit.bill_id, owner: deposit.depositor };
98
+ };
99
+ // ---------------------------------------------------------------------------
100
+ // View function readers (PLAN_001 Etapa 5b — real read skeleton)
101
+ // ---------------------------------------------------------------------------
102
+ // Thin wrappers around `aptos.view(...)` for the specific view functions the
103
+ // SDK needs. Every reader throws on RPC / contract error — callers should
104
+ // wrap in try/catch so a missing deployment degrades gracefully rather than
105
+ // crashing the UI.
106
+ //
107
+ // Shapes are verified against apebond-move-playground pages. See the matching
108
+ // `AptosMarketInfoTuple` / `AptosBillInfo` / `AptosVestingProgressTuple`
109
+ // types for documentation on each field.
110
+ /**
111
+ * `bond::market_info(market)` — returns the 27-element market info tuple.
112
+ */
113
+ const readAptosMarketInfo = async (marketAddress) => {
114
+ const aptos = getAptosClient();
115
+ const result = await aptos.view({
116
+ payload: {
117
+ function: APTOS_VIEW_MARKET_INFO,
118
+ functionArguments: [marketAddress],
119
+ },
120
+ });
121
+ return result;
122
+ };
123
+ /**
124
+ * `bond::bill_info(market, bill_id)` — returns the Bill struct for a
125
+ * specific bill. The contract takes `bill_id: u64` (NOT the object address).
126
+ * Uses REST directly to avoid SDK remoteAbi serialisation bug with u64 args.
127
+ */
128
+ const readAptosBillInfo = async (marketAddress, billId) => {
129
+ const result = await viewViaRest(APTOS_VIEW_BILL_INFO, [marketAddress, billId]);
130
+ return result[0];
131
+ };
132
+ /**
133
+ * `bond_nft::user_bills(user)` — returns all bill_ids owned by the user
134
+ * across every deployed market. The view returns `[bill_ids]` (the inner
135
+ * array is at index 0), so we unwrap it here.
136
+ */
137
+ const readUserBillIds = async (user) => {
138
+ const aptos = getAptosClient();
139
+ const result = await aptos.view({
140
+ payload: {
141
+ function: APTOS_VIEW_USER_BILLS,
142
+ functionArguments: [user],
143
+ },
144
+ });
145
+ const ids = (result[0] ?? []);
146
+ return ids.map((id) => String(id));
147
+ };
148
+ /**
149
+ * `bond::vesting_progress(market, bill_id)` — returns `[vested_amount, claimable_amount]`.
150
+ * Note: this is in `bond` module (not `bond_nft`), and takes the market as first argument.
151
+ * Uses REST directly to avoid SDK remoteAbi serialisation bug with u64 args.
152
+ */
153
+ const readVestingProgress = async (marketAddress, billId) => {
154
+ const result = await viewViaRest(APTOS_VIEW_VESTING_PROGRESS, [marketAddress, billId]);
155
+ return [String(result[0] ?? '0'), String(result[1] ?? '0')];
156
+ };
157
+ // ---------------------------------------------------------------------------
158
+ // REST-based view call — bypasses the SDK's remoteAbi serialisation which
159
+ // has a bug in v6.x where u64 arguments to functions returning `address` get
160
+ // mis-serialised. The REST endpoint handles string arguments natively.
161
+ // ---------------------------------------------------------------------------
162
+ const viewViaRest = async (fn, args, typeArgs = []) => {
163
+ const apiKey = getRandomAptosApiKey();
164
+ const res = await fetch(`${APTOS_FULLNODE_URL}/view`, {
165
+ method: 'POST',
166
+ headers: {
167
+ 'Content-Type': 'application/json',
168
+ ...(apiKey && { Authorization: `Bearer ${apiKey}` }),
169
+ },
170
+ body: JSON.stringify({
171
+ function: fn,
172
+ type_arguments: typeArgs,
173
+ arguments: args,
174
+ }),
175
+ });
176
+ if (!res.ok) {
177
+ const text = await res.text();
178
+ throw new Error(`View call ${fn} failed: ${res.status} ${text}`);
179
+ }
180
+ return (await res.json());
181
+ };
182
+ /**
183
+ * `bond_nft::bond_market_by_id(bill_id)` — which market owns this bill.
184
+ * Uses REST directly — SDK's aptos.view() mis-serialises u64→address functions.
185
+ */
186
+ const readBondMarketByBillId = async (billId) => {
187
+ const result = await viewViaRest(APTOS_VIEW_BOND_MARKET_BY_ID, [billId]);
188
+ return String(result[0] ?? '');
189
+ };
190
+ /**
191
+ * `bond_nft::nft_address(bill_id)` — resolve the scalar bill_id to the
192
+ * on-chain NFT object address (aka `bill_addr`). Needed to then call
193
+ * `bond::bill_info(market, bill_addr)` or `bond::claim(market, bill_addr)`.
194
+ * Uses REST directly — SDK's aptos.view() mis-serialises u64→address functions.
195
+ */
196
+ const readNftAddressByBillId = async (billId) => {
197
+ const result = await viewViaRest(APTOS_VIEW_NFT_ADDRESS, [billId]);
198
+ return String(result[0] ?? '');
199
+ };
200
+
201
+ export { extractBillMinted, extractDepositEvent, extractEventData, getAptosClient, readAptosBillInfo, readAptosMarketInfo, readBondMarketByBillId, readNftAddressByBillId, readUserBillIds, readVestingProgress, safeExtractAddress };
202
+ //# sourceMappingURL=aptosHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aptosHelpers.js","sources":["../../src/utils/aptosHelpers.ts"],"sourcesContent":["import { Aptos, AptosConfig } from '@aptos-labs/ts-sdk'\nimport BigNumber from 'bignumber.js'\nimport {\n APTOS_CLAIM_FUNCTION,\n APTOS_DEPOSIT_FUNCTION,\n APTOS_FULLNODE_URL,\n APTOS_NETWORK,\n APTOS_VIEW_BILL_INFO,\n APTOS_VIEW_BOND_MARKET_BY_ID,\n APTOS_VIEW_MARKET_INFO,\n APTOS_VIEW_NFT_ADDRESS,\n APTOS_VIEW_USER_BILLS,\n APTOS_VIEW_VESTING_PROGRESS,\n getRandomAptosApiKey,\n} from '../constants/aptosConstants'\nimport type {\n AptosBillInfo,\n AptosClaimPayload,\n AptosDepositPayload,\n AptosMarketInfoTuple,\n AptosVestingProgressTuple,\n} from '../types/aptosBonds'\n\n// ---------------------------------------------------------------------------\n// Aptos client — lazy singleton\n// ---------------------------------------------------------------------------\n// We keep one client per (network, api key) pair. The API key is picked with\n// `getRandomAptosApiKey()` on first call, so different sessions hit a\n// different key (very simple load balancing). If the pool is empty we fall\n// back to unauthenticated requests.\nlet _aptosClient: Aptos | undefined\n\nexport const getAptosClient = (): Aptos => {\n if (_aptosClient) return _aptosClient\n const apiKey = getRandomAptosApiKey()\n // The Aptos ts-sdk exposes `API_KEY` directly on `clientConfig`; it adds\n // the `Authorization: Bearer <key>` header internally. This is the\n // idiomatic way to authenticate — no manual header wiring needed.\n const config = new AptosConfig({\n network: APTOS_NETWORK,\n ...(apiKey && { clientConfig: { API_KEY: apiKey } }),\n })\n _aptosClient = new Aptos(config)\n return _aptosClient\n}\n\n// ---------------------------------------------------------------------------\n// Address normalisation\n// ---------------------------------------------------------------------------\n// Aptos wallet adapters can surface account addresses in several shapes:\n// plain string, `{ data: Uint8Array }`, `Uint8Array`, or an `AccountAddress`\n// instance. This helper returns a canonical `0x`-prefixed hex string, or\n// `undefined` if the input cannot be decoded. We keep the interface loose so\n// callers can pass whatever the SDK hands them.\nexport const safeExtractAddress = (input: unknown): string | undefined => {\n if (input == null) return undefined\n\n // Already a string\n if (typeof input === 'string') {\n return input.startsWith('0x') ? input : `0x${input}`\n }\n\n // AccountAddress instance (has `toString()` that returns `0x...`)\n if (typeof input === 'object' && typeof (input as { toString?: () => string }).toString === 'function') {\n const asObject = input as { data?: Uint8Array | number[]; toString: () => string }\n // Prefer `.data` if it looks like a byte array — `.toString()` on\n // AccountAddress already returns the canonical hex, but some wallets\n // return `{ data: Uint8Array }` without the method.\n if (asObject.data instanceof Uint8Array) {\n return bytesToHex(asObject.data)\n }\n if (Array.isArray(asObject.data)) {\n return bytesToHex(new Uint8Array(asObject.data))\n }\n const stringified = asObject.toString()\n if (stringified.startsWith('0x')) return stringified\n }\n\n // Raw Uint8Array\n if (input instanceof Uint8Array) {\n return bytesToHex(input)\n }\n\n // Raw number[]\n if (Array.isArray(input)) {\n return bytesToHex(new Uint8Array(input))\n }\n\n return undefined\n}\n\nconst bytesToHex = (bytes: Uint8Array): string => {\n let out = '0x'\n for (let i = 0; i < bytes.length; i++) {\n out += bytes[i].toString(16).padStart(2, '0')\n }\n return out\n}\n\n// ---------------------------------------------------------------------------\n// Unit conversion\n// ---------------------------------------------------------------------------\n// User inputs live in \"whole tokens\" (e.g. \"1.5 USDC\"). The Aptos ts-sdk\n// serialises numeric function arguments from strings, so we convert to\n// atomic units and return a stringified BigInt.\nexport const toAtomicUnits = (amount: string | number, decimals: number): string => {\n if (amount === '' || amount == null) return '0'\n const bn = new BigNumber(amount).times(new BigNumber(10).pow(decimals))\n // Floor so we never over-spend what the user typed.\n return bn.integerValue(BigNumber.ROUND_FLOOR).toFixed(0)\n}\n\n// ---------------------------------------------------------------------------\n// Payload builders\n// ---------------------------------------------------------------------------\n// These return the `InputEntryFunctionData` shape consumed by\n// `wallet.signAndSubmitTransaction({ sender, data: ... })`. Keeping them in\n// one place means the buy/claim components do not have to repeat the\n// function-name and argument order.\n\nexport const buildDepositPayload = (args: AptosDepositPayload) => ({\n function: APTOS_DEPOSIT_FUNCTION,\n typeArguments: [] as string[],\n functionArguments: [args.market, args.amount, args.max_price, args.depositor] as (string | number)[],\n})\n\nexport const buildClaimPayload = (args: AptosClaimPayload) => ({\n function: APTOS_CLAIM_FUNCTION,\n typeArguments: [] as string[],\n // `apebond::bond::claim(market, bill_id: u64)` — the contract takes the\n // scalar bill_id, NOT the object address.\n functionArguments: [args.market, args.bill_id] as (string | number)[],\n})\n\n// ---------------------------------------------------------------------------\n// Event extractors\n// ---------------------------------------------------------------------------\n// Parse events out of a `waitForTransaction` response. The event `type`\n// format is `${module}::${EventStruct}`. We match by `.endsWith('::Foo')` so\n// we do not have to hard-code the full module path (which contains the\n// contract address).\n\ninterface AptosTxnWithEvents {\n events?: Array<{ type: string; data: Record<string, unknown> }>\n}\n\nexport const extractEventData = <T = Record<string, unknown>>(\n txn: AptosTxnWithEvents,\n eventSuffix: string,\n): T | undefined => {\n const event = txn?.events?.find((e) => e.type.includes(eventSuffix))\n return event?.data as T | undefined\n}\n\n/**\n * `bond::DepositEvent` — emitted by the deposit entry function.\n * Contains bill_id, bill_address, deposit_amount, payout_amount, price.\n */\nexport const extractDepositEvent = (\n txn: AptosTxnWithEvents,\n): { bill_id: string; bill_address: string; market: string; deposit_amount: string; payout_amount: string; price: string; depositor: string; recipient: string } | undefined =>\n extractEventData(txn, '::DepositEvent')\n\n/**\n * Extract bill_id from transaction events. Checks both `BillMinted` (from bond_nft)\n * and `DepositEvent` (from bond) since the contract emits both.\n */\nexport const extractBillMinted = (txn: AptosTxnWithEvents): { bill_id: string; owner: string } | undefined => {\n // Try BillMinted event first (emitted by bond_nft module)\n const billMinted = extractEventData<{ bill_id: string; owner: string }>(txn, '::BillMinted')\n if (billMinted) return billMinted\n // Fall back to DepositEvent (emitted by bond module)\n const deposit = extractDepositEvent(txn)\n if (!deposit) return undefined\n return { bill_id: deposit.bill_id, owner: deposit.depositor }\n}\n\n// ---------------------------------------------------------------------------\n// Fetch helper — GraphQL to the Aptos indexer\n// ---------------------------------------------------------------------------\n// Uses the same API key that is configured on the Aptos client. Everything\n// else on the HTTP layer goes through the Aptos ts-sdk, but the indexer\n// needs a raw `fetch` call because GraphQL is not part of the SDK surface.\nexport const aptosIndexerFetch = async <T = unknown>(\n url: string,\n query: string,\n variables?: Record<string, unknown>,\n): Promise<T> => {\n const apiKey = getRandomAptosApiKey()\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(apiKey && { Authorization: `Bearer ${apiKey}` }),\n },\n body: JSON.stringify({ query, variables }),\n })\n if (!response.ok) {\n throw new Error(`Aptos indexer request failed: ${response.status}`)\n }\n const json = (await response.json()) as { data: T; errors?: Array<{ message: string }> }\n if (json.errors?.length) {\n throw new Error(`Aptos indexer returned errors: ${json.errors.map((e) => e.message).join(', ')}`)\n }\n return json.data\n}\n\n// ---------------------------------------------------------------------------\n// View function readers (PLAN_001 Etapa 5b — real read skeleton)\n// ---------------------------------------------------------------------------\n// Thin wrappers around `aptos.view(...)` for the specific view functions the\n// SDK needs. Every reader throws on RPC / contract error — callers should\n// wrap in try/catch so a missing deployment degrades gracefully rather than\n// crashing the UI.\n//\n// Shapes are verified against apebond-move-playground pages. See the matching\n// `AptosMarketInfoTuple` / `AptosBillInfo` / `AptosVestingProgressTuple`\n// types for documentation on each field.\n\n/**\n * `bond::market_info(market)` — returns the 27-element market info tuple.\n */\nexport const readAptosMarketInfo = async (marketAddress: string): Promise<AptosMarketInfoTuple> => {\n const aptos = getAptosClient()\n const result = await aptos.view({\n payload: {\n function: APTOS_VIEW_MARKET_INFO,\n functionArguments: [marketAddress],\n },\n })\n return result as unknown as AptosMarketInfoTuple\n}\n\n/**\n * `bond::bill_info(market, bill_id)` — returns the Bill struct for a\n * specific bill. The contract takes `bill_id: u64` (NOT the object address).\n * Uses REST directly to avoid SDK remoteAbi serialisation bug with u64 args.\n */\nexport const readAptosBillInfo = async (\n marketAddress: string,\n billId: string,\n): Promise<AptosBillInfo> => {\n const result = await viewViaRest(APTOS_VIEW_BILL_INFO, [marketAddress, billId])\n return result[0] as unknown as AptosBillInfo\n}\n\n/**\n * `bond_nft::user_bills(user)` — returns all bill_ids owned by the user\n * across every deployed market. The view returns `[bill_ids]` (the inner\n * array is at index 0), so we unwrap it here.\n */\nexport const readUserBillIds = async (user: string): Promise<string[]> => {\n const aptos = getAptosClient()\n const result = await aptos.view({\n payload: {\n function: APTOS_VIEW_USER_BILLS,\n functionArguments: [user],\n },\n })\n const ids = (result[0] ?? []) as unknown as Array<string | number>\n return ids.map((id) => String(id))\n}\n\n/**\n * `bond::vesting_progress(market, bill_id)` — returns `[vested_amount, claimable_amount]`.\n * Note: this is in `bond` module (not `bond_nft`), and takes the market as first argument.\n * Uses REST directly to avoid SDK remoteAbi serialisation bug with u64 args.\n */\nexport const readVestingProgress = async (marketAddress: string, billId: string): Promise<AptosVestingProgressTuple> => {\n const result = await viewViaRest(APTOS_VIEW_VESTING_PROGRESS, [marketAddress, billId])\n return [String(result[0] ?? '0'), String(result[1] ?? '0')] as const\n}\n\n// ---------------------------------------------------------------------------\n// REST-based view call — bypasses the SDK's remoteAbi serialisation which\n// has a bug in v6.x where u64 arguments to functions returning `address` get\n// mis-serialised. The REST endpoint handles string arguments natively.\n// ---------------------------------------------------------------------------\nconst viewViaRest = async (\n fn: string,\n args: string[],\n typeArgs: string[] = [],\n): Promise<unknown[]> => {\n const apiKey = getRandomAptosApiKey()\n const res = await fetch(`${APTOS_FULLNODE_URL}/view`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(apiKey && { Authorization: `Bearer ${apiKey}` }),\n },\n body: JSON.stringify({\n function: fn,\n type_arguments: typeArgs,\n arguments: args,\n }),\n })\n if (!res.ok) {\n const text = await res.text()\n throw new Error(`View call ${fn} failed: ${res.status} ${text}`)\n }\n return (await res.json()) as unknown[]\n}\n\n/**\n * `bond_nft::bond_market_by_id(bill_id)` — which market owns this bill.\n * Uses REST directly — SDK's aptos.view() mis-serialises u64→address functions.\n */\nexport const readBondMarketByBillId = async (billId: string): Promise<string> => {\n const result = await viewViaRest(APTOS_VIEW_BOND_MARKET_BY_ID, [billId])\n return String(result[0] ?? '')\n}\n\n/**\n * `bond_nft::nft_address(bill_id)` — resolve the scalar bill_id to the\n * on-chain NFT object address (aka `bill_addr`). Needed to then call\n * `bond::bill_info(market, bill_addr)` or `bond::claim(market, bill_addr)`.\n * Uses REST directly — SDK's aptos.view() mis-serialises u64→address functions.\n */\nexport const readNftAddressByBillId = async (billId: string): Promise<string> => {\n const result = await viewViaRest(APTOS_VIEW_NFT_ADDRESS, [billId])\n return String(result[0] ?? '')\n}\n"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import '../config/constants/tokens.js';
1
2
  import { WNATIVE } from '@ape.swap/apeswap-lists';
2
3
 
3
4
  const getNativeTicker = (chain) => {
@@ -1 +1 @@
1
- {"version":3,"file":"getNativeTicker.js","sources":["../../src/utils/getNativeTicker.ts"],"sourcesContent":["import { ChainId, Token } from '@ape.swap/apeswap-lists'\nimport { WNATIVE } from '../config/constants/tokens'\n\nconst getNativeTicker = (chain?: ChainId) => {\n if (!chain) return undefined\n return WNATIVE[chain]?.symbol.substring(1)\n}\n\nconst getTokenSymbol = (token: Token) => {\n const nativeSymbols = ['BNB', 'ETH', 'POL', 'IOTA']\n return nativeSymbols.includes(token?.symbol) ? `w${token?.symbol}` : token?.symbol\n}\n\nexport const getSymbol = (token?: Token | 'NATIVE', chainId?: ChainId) => {\n if (!token) return ''\n return token === 'NATIVE' ? getNativeTicker(chainId) : getTokenSymbol(token)\n}\n"],"names":[],"mappings":";;AAGA,MAAM,eAAe,GAAG,CAAC,KAAe,KAAI;AAC1C,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,SAAS;IAC5B,OAAO,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,cAAc,GAAG,CAAC,KAAY,KAAI;IACtC,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC;IACnD,OAAO,aAAa,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,KAAK,EAAE,MAAM,CAAA,CAAE,GAAG,KAAK,EAAE,MAAM;AACpF,CAAC;MAEY,SAAS,GAAG,CAAC,KAAwB,EAAE,OAAiB,KAAI;AACvE,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,EAAE;AACrB,IAAA,OAAO,KAAK,KAAK,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC;AAC9E;;;;"}
1
+ {"version":3,"file":"getNativeTicker.js","sources":["../../src/utils/getNativeTicker.ts"],"sourcesContent":["import { ChainId, Token } from '@ape.swap/apeswap-lists'\nimport { WNATIVE } from '../config/constants/tokens'\n\nconst getNativeTicker = (chain?: ChainId) => {\n if (!chain) return undefined\n return WNATIVE[chain]?.symbol.substring(1)\n}\n\nconst getTokenSymbol = (token: Token) => {\n const nativeSymbols = ['BNB', 'ETH', 'POL', 'IOTA']\n return nativeSymbols.includes(token?.symbol) ? `w${token?.symbol}` : token?.symbol\n}\n\nexport const getSymbol = (token?: Token | 'NATIVE', chainId?: ChainId) => {\n if (!token) return ''\n return token === 'NATIVE' ? getNativeTicker(chainId) : getTokenSymbol(token)\n}\n"],"names":[],"mappings":";;;AAGA,MAAM,eAAe,GAAG,CAAC,KAAe,KAAI;AAC1C,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,SAAS;IAC5B,OAAO,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,cAAc,GAAG,CAAC,KAAY,KAAI;IACtC,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC;IACnD,OAAO,aAAa,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,KAAK,EAAE,MAAM,CAAA,CAAE,GAAG,KAAK,EAAE,MAAM;AACpF,CAAC;MAEY,SAAS,GAAG,CAAC,KAAwB,EAAE,OAAiB,KAAI;AACvE,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,EAAE;AACrB,IAAA,OAAO,KAAK,KAAK,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC;AAC9E;;;;"}
@@ -0,0 +1,6 @@
1
+ import { SuiClient } from '@mysten/sui/client';
2
+ export declare const getSuiClient: () => SuiClient;
3
+ export declare const toAtomicUnits: (amount: string | number, decimals: number) => string;
4
+ export declare const fromAtomicUnits: (amount: string | number, decimals: number) => number;
5
+ export declare const readFreshTrueBondPrice: (marketObjectId: string) => Promise<bigint>;
6
+ export declare const verifySuiTxSuccess: (digest: string) => Promise<void>;
@@ -0,0 +1,106 @@
1
+ import { SuiClient } from '@mysten/sui/client';
2
+ import BigNumber from 'bignumber.js';
3
+ import { SUI_FULLNODE_URL } from '../constants/suiConstants.js';
4
+
5
+ // ---------------------------------------------------------------------------
6
+ // Sui client — lazy singleton
7
+ // ---------------------------------------------------------------------------
8
+ let _suiClient;
9
+ const getSuiClient = () => {
10
+ if (_suiClient)
11
+ return _suiClient;
12
+ _suiClient = new SuiClient({ url: SUI_FULLNODE_URL });
13
+ return _suiClient;
14
+ };
15
+ // ---------------------------------------------------------------------------
16
+ // Unit conversion
17
+ // ---------------------------------------------------------------------------
18
+ // User inputs live in "whole tokens" (e.g. "1.5 SUI"). The Sui SDK
19
+ // serialises numeric function arguments from strings, so we convert to
20
+ // atomic units and return a stringified BigInt.
21
+ const toAtomicUnits = (amount, decimals) => {
22
+ if (amount === '' || amount == null)
23
+ return '0';
24
+ const bn = new BigNumber(amount).times(new BigNumber(10).pow(decimals));
25
+ // Floor so we never over-spend what the user typed.
26
+ return bn.integerValue(BigNumber.ROUND_FLOOR).toFixed(0);
27
+ };
28
+ // Atomic → human-readable.
29
+ const fromAtomicUnits = (amount, decimals) => {
30
+ if (amount === '' || amount == null)
31
+ return 0;
32
+ return new BigNumber(amount).div(new BigNumber(10).pow(decimals)).toNumber();
33
+ };
34
+ // ---------------------------------------------------------------------------
35
+ // Fresh bond price reader — reads the BondMarket object on-chain and
36
+ // computes the current true_price using the same bond_math formulas as
37
+ // the Move contract. Returns the u64 value (scaled 1e8).
38
+ // ---------------------------------------------------------------------------
39
+ const PRICE_DECIMALS = 100000000n; // 1e8
40
+ const PERCENTAGE_BASE = 1000000n; // 1e6
41
+ const pow10bi = (n) => 10n ** BigInt(n);
42
+ const valueOfToken = (fromDec, toDec, amount) => {
43
+ if (toDec >= fromDec)
44
+ return amount * pow10bi(toDec - fromDec);
45
+ return amount / pow10bi(fromDec - toDec);
46
+ };
47
+ const readFreshTrueBondPrice = async (marketObjectId) => {
48
+ const client = getSuiClient();
49
+ const obj = await client.getObject({ id: marketObjectId, options: { showContent: true } });
50
+ if (!obj.data?.content || obj.data.content.dataType !== 'moveObject') {
51
+ throw new Error(`[Sui] Could not read BondMarket ${marketObjectId}`);
52
+ }
53
+ const f = obj.data.content.fields;
54
+ const terms = f.terms?.fields ??
55
+ f.terms;
56
+ const totalDebt = BigInt(String(f.total_debt ?? '0'));
57
+ const payoutInitialSupply = BigInt(String(f.payout_token_initial_supply ?? '0'));
58
+ const controlVariable = BigInt(String(terms.control_variable ?? '0'));
59
+ const minimumPrice = BigInt(String(terms.minimum_price ?? '0'));
60
+ const vestingTerm = BigInt(String(terms.vesting_term ?? '1'));
61
+ const lastDecay = BigInt(String(f.last_decay ?? '0'));
62
+ const feeInPrincipal = BigInt(String(f.fee_in_principal ?? '0'));
63
+ const payoutDecimals = Number(f.payout_decimals ?? 9);
64
+ const principalDecimals = Number(f.principal_decimals ?? 9);
65
+ // Decay debt client-side (same as contract's decay_debt)
66
+ const nowSeconds = BigInt(Math.floor(Date.now() / 1000));
67
+ let currentDebt = totalDebt;
68
+ if (nowSeconds > lastDecay && vestingTerm > 0n) {
69
+ const elapsed = nowSeconds - lastDecay;
70
+ const decay = (totalDebt * elapsed) / vestingTerm;
71
+ currentDebt = totalDebt > decay ? totalDebt - decay : 0n;
72
+ }
73
+ // calculate_price — contract casts total_debt (u128) to u64 via `as u64`
74
+ const currentDebtU64 = currentDebt & 0xffffffffffffffffn;
75
+ const currentDebtPayout = valueOfToken(principalDecimals, payoutDecimals, currentDebtU64);
76
+ const payoutScale = pow10bi(payoutDecimals);
77
+ const principalScale = pow10bi(principalDecimals);
78
+ const debtRatio = payoutInitialSupply > 0n
79
+ ? (currentDebtPayout * payoutScale) / payoutInitialSupply
80
+ : 0n;
81
+ const basePrice = (controlVariable * debtRatio * principalScale) / PRICE_DECIMALS;
82
+ const price = basePrice < minimumPrice ? minimumPrice : basePrice;
83
+ // calculate_true_price (includes fee)
84
+ const denominator = PERCENTAGE_BASE - feeInPrincipal;
85
+ const truePrice = denominator > 0n ? (price * PERCENTAGE_BASE) / denominator : price;
86
+ return truePrice;
87
+ };
88
+ // ---------------------------------------------------------------------------
89
+ // TX status verification — Sui returns digests for failed TXs too.
90
+ // Call this after waitForTransaction to ensure the TX actually succeeded.
91
+ // ---------------------------------------------------------------------------
92
+ const verifySuiTxSuccess = async (digest) => {
93
+ const client = getSuiClient();
94
+ const txBlock = await client.getTransactionBlock({
95
+ digest,
96
+ options: { showEffects: true },
97
+ });
98
+ const status = txBlock.effects?.status;
99
+ if (status?.status !== 'success') {
100
+ const errorMsg = status?.error ?? 'Transaction failed on-chain';
101
+ throw new Error(`Transaction failed: ${errorMsg}`);
102
+ }
103
+ };
104
+
105
+ export { fromAtomicUnits, getSuiClient, readFreshTrueBondPrice, toAtomicUnits, verifySuiTxSuccess };
106
+ //# sourceMappingURL=suiHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suiHelpers.js","sources":["../../src/utils/suiHelpers.ts"],"sourcesContent":["import { SuiClient } from '@mysten/sui/client'\nimport BigNumber from 'bignumber.js'\nimport { SUI_FULLNODE_URL } from '../constants/suiConstants'\n\n// ---------------------------------------------------------------------------\n// Sui client — lazy singleton\n// ---------------------------------------------------------------------------\nlet _suiClient: SuiClient | undefined\n\nexport const getSuiClient = (): SuiClient => {\n if (_suiClient) return _suiClient\n _suiClient = new SuiClient({ url: SUI_FULLNODE_URL })\n return _suiClient\n}\n\n// ---------------------------------------------------------------------------\n// Unit conversion\n// ---------------------------------------------------------------------------\n// User inputs live in \"whole tokens\" (e.g. \"1.5 SUI\"). The Sui SDK\n// serialises numeric function arguments from strings, so we convert to\n// atomic units and return a stringified BigInt.\nexport const toAtomicUnits = (amount: string | number, decimals: number): string => {\n if (amount === '' || amount == null) return '0'\n const bn = new BigNumber(amount).times(new BigNumber(10).pow(decimals))\n // Floor so we never over-spend what the user typed.\n return bn.integerValue(BigNumber.ROUND_FLOOR).toFixed(0)\n}\n\n// Atomic → human-readable.\nexport const fromAtomicUnits = (amount: string | number, decimals: number): number => {\n if (amount === '' || amount == null) return 0\n return new BigNumber(amount).div(new BigNumber(10).pow(decimals)).toNumber()\n}\n\n// ---------------------------------------------------------------------------\n// Fresh bond price reader — reads the BondMarket object on-chain and\n// computes the current true_price using the same bond_math formulas as\n// the Move contract. Returns the u64 value (scaled 1e8).\n// ---------------------------------------------------------------------------\n\nconst PRICE_DECIMALS = 100_000_000n // 1e8\nconst PERCENTAGE_BASE = 1_000_000n // 1e6\n\nconst pow10bi = (n: number): bigint => 10n ** BigInt(n)\n\nconst valueOfToken = (fromDec: number, toDec: number, amount: bigint): bigint => {\n if (toDec >= fromDec) return amount * pow10bi(toDec - fromDec)\n return amount / pow10bi(fromDec - toDec)\n}\n\nexport const readFreshTrueBondPrice = async (marketObjectId: string): Promise<bigint> => {\n const client = getSuiClient()\n const obj = await client.getObject({ id: marketObjectId, options: { showContent: true } })\n\n if (!obj.data?.content || obj.data.content.dataType !== 'moveObject') {\n throw new Error(`[Sui] Could not read BondMarket ${marketObjectId}`)\n }\n\n const f = obj.data.content.fields as Record<string, unknown>\n const terms = (f.terms as Record<string, unknown>)?.fields as Record<string, unknown> ??\n f.terms as Record<string, unknown>\n\n const totalDebt = BigInt(String(f.total_debt ?? '0'))\n const payoutInitialSupply = BigInt(String(f.payout_token_initial_supply ?? '0'))\n const controlVariable = BigInt(String(terms.control_variable ?? '0'))\n const minimumPrice = BigInt(String(terms.minimum_price ?? '0'))\n const vestingTerm = BigInt(String(terms.vesting_term ?? '1'))\n const lastDecay = BigInt(String(f.last_decay ?? '0'))\n const feeInPrincipal = BigInt(String(f.fee_in_principal ?? '0'))\n const payoutDecimals = Number(f.payout_decimals ?? 9)\n const principalDecimals = Number(f.principal_decimals ?? 9)\n\n // Decay debt client-side (same as contract's decay_debt)\n const nowSeconds = BigInt(Math.floor(Date.now() / 1000))\n let currentDebt = totalDebt\n if (nowSeconds > lastDecay && vestingTerm > 0n) {\n const elapsed = nowSeconds - lastDecay\n const decay = (totalDebt * elapsed) / vestingTerm\n currentDebt = totalDebt > decay ? totalDebt - decay : 0n\n }\n\n // calculate_price — contract casts total_debt (u128) to u64 via `as u64`\n const currentDebtU64 = currentDebt & 0xFFFFFFFFFFFFFFFFn\n const currentDebtPayout = valueOfToken(principalDecimals, payoutDecimals, currentDebtU64)\n const payoutScale = pow10bi(payoutDecimals)\n const principalScale = pow10bi(principalDecimals)\n\n const debtRatio = payoutInitialSupply > 0n\n ? (currentDebtPayout * payoutScale) / payoutInitialSupply\n : 0n\n const basePrice = (controlVariable * debtRatio * principalScale) / PRICE_DECIMALS\n\n const price = basePrice < minimumPrice ? minimumPrice : basePrice\n\n // calculate_true_price (includes fee)\n const denominator = PERCENTAGE_BASE - feeInPrincipal\n const truePrice = denominator > 0n ? (price * PERCENTAGE_BASE) / denominator : price\n\n return truePrice\n}\n\n// ---------------------------------------------------------------------------\n// TX status verification — Sui returns digests for failed TXs too.\n// Call this after waitForTransaction to ensure the TX actually succeeded.\n// ---------------------------------------------------------------------------\n\nexport const verifySuiTxSuccess = async (digest: string): Promise<void> => {\n const client = getSuiClient()\n const txBlock = await client.getTransactionBlock({\n digest,\n options: { showEffects: true },\n })\n const status = txBlock.effects?.status\n if (status?.status !== 'success') {\n const errorMsg = status?.error ?? 'Transaction failed on-chain'\n throw new Error(`Transaction failed: ${errorMsg}`)\n }\n}\n"],"names":[],"mappings":"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"}