@neutral-trade/sdk 0.4.4 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -199,6 +199,51 @@ declare function parseAmountRawToBigInt(amountRaw: string): bigint;
199
199
  */
200
200
  declare function humanFloatToAmountRawString(human: number, decimals: number): string;
201
201
  //#endregion
202
+ //#region src/utils/bundle-fee-override.d.ts
203
+ /** Mirrors `bundle-sc` `FEE_OVERRIDE_*` bit flags. */
204
+ declare const FEE_OVERRIDE: {
205
+ readonly DEPOSIT: number;
206
+ readonly WITHDRAWAL: number;
207
+ readonly PERFORMANCE: number;
208
+ readonly MANAGEMENT: number;
209
+ };
210
+ interface EffectiveFeeBps {
211
+ depositFeeBps: number;
212
+ withdrawalFeeBps: number;
213
+ performanceFeeBps: number;
214
+ managementFeeBps: number;
215
+ }
216
+ /** Decimal fees matching frontend `VaultConfig` (`0.01` = 1%). */
217
+ interface EffectiveVaultFeeDecimals {
218
+ dfee: number;
219
+ wfee: number;
220
+ pfee: number;
221
+ mfee: number;
222
+ }
223
+ declare function bpsToFeeDecimal(bps: number): number;
224
+ declare function feeDecimalToBps(decimal: number): number;
225
+ declare function vaultFeeDecimalsToBps(fees: EffectiveVaultFeeDecimals): EffectiveFeeBps;
226
+ declare function effectiveFeeBpsToDecimals(fees: EffectiveFeeBps): EffectiveVaultFeeDecimals;
227
+ /**
228
+ * Apply per-user fee override flags onto default bps (bundle or vault-config defaults).
229
+ */
230
+ declare function resolveEffectiveFeeBpsFromDefaults(defaults: EffectiveFeeBps, user: UserBundleAccount): EffectiveFeeBps;
231
+ /**
232
+ * Mirror on-chain `resolve_effective_fees`. Returns fee rates in bps.
233
+ */
234
+ declare function resolveEffectiveFeeBps(bundle: BundleAccount, user: UserBundleAccount): EffectiveFeeBps;
235
+ /**
236
+ * Resolve effective fees for UI vault config defaults + optional user bundle account.
237
+ * Returns decimal fees (`0.01` = 1%).
238
+ */
239
+ declare function resolveEffectiveVaultFees(vaultDefaults: EffectiveVaultFeeDecimals, user?: UserBundleAccount | null): EffectiveVaultFeeDecimals;
240
+ declare function hasAnyFeeOverride(user?: UserBundleAccount | null): boolean;
241
+ declare function hasCustomFeeRate(effectiveFees: EffectiveVaultFeeDecimals, vaultDefaults: EffectiveVaultFeeDecimals): boolean;
242
+ declare function computeDepositFeePreview(grossAmount: number, depositFeeDecimal: number): {
243
+ feeAmount: number;
244
+ netAmount: number;
245
+ };
246
+ //#endregion
202
247
  //#region src/utils/request-withdraw-shares.d.ts
203
248
  /**
204
249
  * Shares to burn for `requestWithdrawal`, from integer token raw and on-chain totals.
@@ -281,4 +326,4 @@ declare function derivePendingAuthPDA(bundlePDA: PublicKey, programId: PublicKey
281
326
  */
282
327
  declare function getVaultDepositorAddressSync(programId: PublicKey, vault: PublicKey, authority: PublicKey): PublicKey;
283
328
  //#endregion
284
- export { ALLOWLISTED_BUNDLE_PROGRAM_IDS_BY_CLUSTER, BUNDLE_PROGRAM_ID_V2_MAINNET, type BuildBundleDepositInstructionsParams, type BuildBundleRequestWithdrawInstructionParams, type BundleAccount, type BundleCluster, type BundleProgram, type BundleProvider, DEFAULT_BUNDLE_PROGRAM_ID_DEVNET, DEFAULT_BUNDLE_PROGRAM_ID_MAINNET, DevnetVaultId, NeutralTrade, type NeutralTradeConfig, type NeutralTradeCoreContext, type OracleData, SEED_ORACLE, SEED_PENDING_AUTH, SEED_TEMP, SEED_USER, SupportedChain, SupportedToken, type Token, type UserBalanceResult, type UserBundleAccount, type UserBundleTempData, type VaultBalanceData, VaultCategory, VaultId, type VaultRegistry, type VaultRegistryEntry, VaultType, assertAllowlistedBundleProgramId, buildBundleDepositInstructions, buildBundleRequestWithdrawInstruction, computeRequestWithdrawalSharesFromAmountRaw, createAllowlistedBundleProgram, createBundleProgramById, createDummyWallet, deriveOraclePDA, derivePendingAuthPDA, deriveTempDataPDA, deriveUserPDA, getBundleProgramId, getDefaultBundleProgramIdByCluster, getSolanaTokenDecimals, getSolanaTokenMint, getVaultByAddress, getVaultById, getVaultDepositorAddressSync, getVaultRegistry, humanFloatToAmountRawString, isAllowlistedBundleProgramId, isValidVaultAddress, parseAmountRawToBigInt, tokens, vaults, vaultsDevnet };
329
+ export { ALLOWLISTED_BUNDLE_PROGRAM_IDS_BY_CLUSTER, BUNDLE_PROGRAM_ID_V2_MAINNET, type BuildBundleDepositInstructionsParams, type BuildBundleRequestWithdrawInstructionParams, type BundleAccount, type BundleCluster, type BundleProgram, type BundleProvider, DEFAULT_BUNDLE_PROGRAM_ID_DEVNET, DEFAULT_BUNDLE_PROGRAM_ID_MAINNET, DevnetVaultId, type EffectiveFeeBps, type EffectiveVaultFeeDecimals, FEE_OVERRIDE, NeutralTrade, type NeutralTradeConfig, type NeutralTradeCoreContext, type OracleData, SEED_ORACLE, SEED_PENDING_AUTH, SEED_TEMP, SEED_USER, SupportedChain, SupportedToken, type Token, type UserBalanceResult, type UserBundleAccount, type UserBundleTempData, type VaultBalanceData, VaultCategory, VaultId, type VaultRegistry, type VaultRegistryEntry, VaultType, assertAllowlistedBundleProgramId, bpsToFeeDecimal, buildBundleDepositInstructions, buildBundleRequestWithdrawInstruction, computeDepositFeePreview, computeRequestWithdrawalSharesFromAmountRaw, createAllowlistedBundleProgram, createBundleProgramById, createDummyWallet, deriveOraclePDA, derivePendingAuthPDA, deriveTempDataPDA, deriveUserPDA, effectiveFeeBpsToDecimals, feeDecimalToBps, getBundleProgramId, getDefaultBundleProgramIdByCluster, getSolanaTokenDecimals, getSolanaTokenMint, getVaultByAddress, getVaultById, getVaultDepositorAddressSync, getVaultRegistry, hasAnyFeeOverride, hasCustomFeeRate, humanFloatToAmountRawString, isAllowlistedBundleProgramId, isValidVaultAddress, parseAmountRawToBigInt, resolveEffectiveFeeBps, resolveEffectiveFeeBpsFromDefaults, resolveEffectiveVaultFees, tokens, vaultFeeDecimalsToBps, vaults, vaultsDevnet };
package/dist/index.mjs CHANGED
@@ -184,6 +184,99 @@ let DevnetVaultId = /* @__PURE__ */ function(DevnetVaultId$1) {
184
184
  return DevnetVaultId$1;
185
185
  }({});
186
186
 
187
+ //#endregion
188
+ //#region src/utils/bundle-fee-override.ts
189
+ /** Mirrors `bundle-sc` `FEE_OVERRIDE_*` bit flags. */
190
+ const FEE_OVERRIDE = {
191
+ DEPOSIT: 1,
192
+ WITHDRAWAL: 2,
193
+ PERFORMANCE: 4,
194
+ MANAGEMENT: 8
195
+ };
196
+ const FEE_EPS = 1e-9;
197
+ function bpsToFeeDecimal(bps) {
198
+ return bps / 1e4;
199
+ }
200
+ function feeDecimalToBps(decimal) {
201
+ return Math.round(decimal * 1e4);
202
+ }
203
+ function toNum(value) {
204
+ if (typeof value === "number") return value;
205
+ if (typeof value === "bigint") return Number(value);
206
+ if (typeof value === "object" && value !== null && "toNumber" in value) return value.toNumber();
207
+ return Number(String(value ?? 0));
208
+ }
209
+ function bundleDefaultFeeBps(bundle) {
210
+ const b = bundle;
211
+ return {
212
+ depositFeeBps: toNum(b.depositFee),
213
+ withdrawalFeeBps: toNum(b.withdrawalFee),
214
+ performanceFeeBps: toNum(b.performanceFee),
215
+ managementFeeBps: toNum(b.managementFeeBps)
216
+ };
217
+ }
218
+ function vaultFeeDecimalsToBps(fees) {
219
+ return {
220
+ depositFeeBps: feeDecimalToBps(fees.dfee),
221
+ withdrawalFeeBps: feeDecimalToBps(fees.wfee),
222
+ performanceFeeBps: feeDecimalToBps(fees.pfee),
223
+ managementFeeBps: feeDecimalToBps(fees.mfee)
224
+ };
225
+ }
226
+ function effectiveFeeBpsToDecimals(fees) {
227
+ return {
228
+ dfee: bpsToFeeDecimal(fees.depositFeeBps),
229
+ wfee: bpsToFeeDecimal(fees.withdrawalFeeBps),
230
+ pfee: bpsToFeeDecimal(fees.performanceFeeBps),
231
+ mfee: bpsToFeeDecimal(fees.managementFeeBps)
232
+ };
233
+ }
234
+ /**
235
+ * Apply per-user fee override flags onto default bps (bundle or vault-config defaults).
236
+ */
237
+ function resolveEffectiveFeeBpsFromDefaults(defaults, user) {
238
+ const flags = toNum(user.feeOverrideFlags);
239
+ if (flags === 0) return defaults;
240
+ return {
241
+ depositFeeBps: (flags & FEE_OVERRIDE.DEPOSIT) !== 0 ? toNum(user.customDepositFeeBps) : defaults.depositFeeBps,
242
+ withdrawalFeeBps: (flags & FEE_OVERRIDE.WITHDRAWAL) !== 0 ? toNum(user.customWithdrawalFeeBps) : defaults.withdrawalFeeBps,
243
+ performanceFeeBps: (flags & FEE_OVERRIDE.PERFORMANCE) !== 0 ? toNum(user.customPerformanceFeeBps) : defaults.performanceFeeBps,
244
+ managementFeeBps: (flags & FEE_OVERRIDE.MANAGEMENT) !== 0 ? toNum(user.customManagementFeeBps) : defaults.managementFeeBps
245
+ };
246
+ }
247
+ /**
248
+ * Mirror on-chain `resolve_effective_fees`. Returns fee rates in bps.
249
+ */
250
+ function resolveEffectiveFeeBps(bundle, user) {
251
+ return resolveEffectiveFeeBpsFromDefaults(bundleDefaultFeeBps(bundle), user);
252
+ }
253
+ /**
254
+ * Resolve effective fees for UI vault config defaults + optional user bundle account.
255
+ * Returns decimal fees (`0.01` = 1%).
256
+ */
257
+ function resolveEffectiveVaultFees(vaultDefaults, user) {
258
+ if (!user) return vaultDefaults;
259
+ return effectiveFeeBpsToDecimals(resolveEffectiveFeeBpsFromDefaults(vaultFeeDecimalsToBps(vaultDefaults), user));
260
+ }
261
+ function hasAnyFeeOverride(user) {
262
+ if (!user) return false;
263
+ return toNum(user.feeOverrideFlags) !== 0;
264
+ }
265
+ function hasCustomFeeRate(effectiveFees, vaultDefaults) {
266
+ return Math.abs(effectiveFees.dfee - vaultDefaults.dfee) > FEE_EPS || Math.abs(effectiveFees.wfee - vaultDefaults.wfee) > FEE_EPS || Math.abs(effectiveFees.pfee - vaultDefaults.pfee) > FEE_EPS || Math.abs(effectiveFees.mfee - vaultDefaults.mfee) > FEE_EPS;
267
+ }
268
+ function computeDepositFeePreview(grossAmount, depositFeeDecimal) {
269
+ if (grossAmount <= 0 || depositFeeDecimal <= 0) return {
270
+ feeAmount: 0,
271
+ netAmount: grossAmount
272
+ };
273
+ const feeAmount = grossAmount * depositFeeDecimal;
274
+ return {
275
+ feeAmount,
276
+ netAmount: grossAmount - feeAmount
277
+ };
278
+ }
279
+
187
280
  //#endregion
188
281
  //#region src/utils/bundle.ts
189
282
  const SECONDS_PER_YEAR = 365n * 24n * 60n * 60n;
@@ -202,8 +295,9 @@ function estimatePendingBundleFeeToken({ oracleData, bundleData, userBundle, ass
202
295
  const extra = bundleData;
203
296
  const assetPrec = extra.assetPrecision != null ? BigInt(extra.assetPrecision.toString()) : BigInt(10 ** assetDecimals);
204
297
  const sharePrice = totalShares > 0n ? totalAssets * assetPrec / totalShares : assetPrec;
205
- const managementFeeBps = BigInt(Number(extra.managementFeeBps ?? 0));
206
- const performanceFeeBps = BigInt(Number(extra.performanceFee ?? 0));
298
+ const effectiveFees = resolveEffectiveFeeBps(bundleData, userBundle);
299
+ const managementFeeBps = BigInt(effectiveFees.managementFeeBps);
300
+ const performanceFeeBps = BigInt(effectiveFees.performanceFeeBps);
207
301
  const lastMgmtTs = bnToBigInt(userBundle.lastManagementFeeTimestamp);
208
302
  const nowTs = BigInt(nowUnixSeconds);
209
303
  let managementFeeShares = 0n;
@@ -406,4 +500,4 @@ var NeutralTrade = class NeutralTrade {
406
500
  };
407
501
 
408
502
  //#endregion
409
- export { ALLOWLISTED_BUNDLE_PROGRAM_IDS_BY_CLUSTER, BUNDLE_PROGRAM_ID_V2_MAINNET, DEFAULT_BUNDLE_PROGRAM_ID_DEVNET, DEFAULT_BUNDLE_PROGRAM_ID_MAINNET, DevnetVaultId, NeutralTrade, SEED_ORACLE, SEED_PENDING_AUTH, SEED_TEMP, SEED_USER, SupportedChain, SupportedToken, VaultCategory, VaultId, VaultType, assertAllowlistedBundleProgramId, buildBundleDepositInstructions, buildBundleRequestWithdrawInstruction, computeRequestWithdrawalSharesFromAmountRaw, createAllowlistedBundleProgram, createBundleProgramById, createDummyWallet, deriveOraclePDA, derivePendingAuthPDA, deriveTempDataPDA, deriveUserPDA, getBundleProgramId, getDefaultBundleProgramIdByCluster, getSolanaTokenDecimals, getSolanaTokenMint, getVaultByAddress, getVaultById, getVaultDepositorAddressSync, getVaultRegistry, humanFloatToAmountRawString, isAllowlistedBundleProgramId, isValidVaultAddress, parseAmountRawToBigInt, tokens, vaults, vaultsDevnet };
503
+ export { ALLOWLISTED_BUNDLE_PROGRAM_IDS_BY_CLUSTER, BUNDLE_PROGRAM_ID_V2_MAINNET, DEFAULT_BUNDLE_PROGRAM_ID_DEVNET, DEFAULT_BUNDLE_PROGRAM_ID_MAINNET, DevnetVaultId, FEE_OVERRIDE, NeutralTrade, SEED_ORACLE, SEED_PENDING_AUTH, SEED_TEMP, SEED_USER, SupportedChain, SupportedToken, VaultCategory, VaultId, VaultType, assertAllowlistedBundleProgramId, bpsToFeeDecimal, buildBundleDepositInstructions, buildBundleRequestWithdrawInstruction, computeDepositFeePreview, computeRequestWithdrawalSharesFromAmountRaw, createAllowlistedBundleProgram, createBundleProgramById, createDummyWallet, deriveOraclePDA, derivePendingAuthPDA, deriveTempDataPDA, deriveUserPDA, effectiveFeeBpsToDecimals, feeDecimalToBps, getBundleProgramId, getDefaultBundleProgramIdByCluster, getSolanaTokenDecimals, getSolanaTokenMint, getVaultByAddress, getVaultById, getVaultDepositorAddressSync, getVaultRegistry, hasAnyFeeOverride, hasCustomFeeRate, humanFloatToAmountRawString, isAllowlistedBundleProgramId, isValidVaultAddress, parseAmountRawToBigInt, resolveEffectiveFeeBps, resolveEffectiveFeeBpsFromDefaults, resolveEffectiveVaultFees, tokens, vaultFeeDecimalsToBps, vaults, vaultsDevnet };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@neutral-trade/sdk",
3
3
  "type": "module",
4
- "version": "0.4.4",
4
+ "version": "0.4.5",
5
5
  "description": "SDK for Neutral Trade vaults",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/neutral-trade/sdk#readme",