@neutral-trade/sdk 0.2.3 → 0.2.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
@@ -1,6 +1,6 @@
1
- import { AnchorProvider, IdlAccounts, Program, Wallet } from "@coral-xyz/anchor";
1
+ import { AnchorProvider, BN, IdlAccounts, Program, Wallet } from "@coral-xyz/anchor";
2
2
  import { AnchorProvider as AnchorProvider$1, IdlAccounts as IdlAccounts$1, Program as Program$1 } from "@coral-xyz/anchor-32";
3
- import { Connection, PublicKey } from "@solana/web3.js";
3
+ import { Connection, PublicKey, TransactionInstruction } from "@solana/web3.js";
4
4
  import { z } from "zod";
5
5
 
6
6
  //#region src/constants/client.d.ts
@@ -5291,6 +5291,32 @@ declare class NeutralTrade {
5291
5291
  vaultIds: number[];
5292
5292
  userAddress: string;
5293
5293
  }): Promise<UserBalanceResult>;
5294
+ /**
5295
+ * Build deposit instructions (optional init + requestDeposit). Fetches vault state on-chain.
5296
+ */
5297
+ buildDepositInstructions({
5298
+ vaultId,
5299
+ userAddress,
5300
+ amount,
5301
+ needsInit
5302
+ }: {
5303
+ vaultId: number;
5304
+ userAddress: string;
5305
+ amount: number;
5306
+ needsInit?: boolean;
5307
+ }): Promise<TransactionInstruction[]>;
5308
+ /**
5309
+ * Build request-withdraw instruction. Fetches vault, oracle, and depositor accounts on-chain.
5310
+ */
5311
+ buildRequestWithdrawInstruction({
5312
+ vaultId,
5313
+ userAddress,
5314
+ amount
5315
+ }: {
5316
+ vaultId: number;
5317
+ userAddress: string;
5318
+ amount: number;
5319
+ }): Promise<TransactionInstruction>;
5294
5320
  }
5295
5321
  //#endregion
5296
5322
  //#region src/utils/bundle.d.ts
@@ -5311,6 +5337,59 @@ declare function estimatePendingBundleFeeToken({
5311
5337
  nowUnixSeconds?: number;
5312
5338
  }): number;
5313
5339
  //#endregion
5340
+ //#region src/utils/bundle-instructions.d.ts
5341
+ interface BuildBundleDepositInstructionsParams {
5342
+ bundleProgramV1: Program<NtbundleV1>;
5343
+ bundleProgramV2: Program$1<NtbundleV2>;
5344
+ vault: VaultRegistryEntry;
5345
+ user: PublicKey;
5346
+ /** UI token amount (multiplied by 10**on-chain decimals inside). */
5347
+ amount: number;
5348
+ needsInit?: boolean;
5349
+ }
5350
+ interface BuildBundleRequestWithdrawInstructionParams {
5351
+ bundleProgramV1: Program<NtbundleV1>;
5352
+ bundleProgramV2: Program$1<NtbundleV2>;
5353
+ vault: VaultRegistryEntry;
5354
+ user: PublicKey;
5355
+ amount: number;
5356
+ }
5357
+ /** Same share math as legacy app `useBundleRequestWithdrawMutation`. */
5358
+ declare function computeRequestWithdrawalSharesAmount({
5359
+ amount,
5360
+ userVaultBalance,
5361
+ pps,
5362
+ assetDecimals,
5363
+ userShares
5364
+ }: {
5365
+ amount: number;
5366
+ userVaultBalance: number;
5367
+ pps: number;
5368
+ assetDecimals: number;
5369
+ userShares: BN;
5370
+ }): BN;
5371
+ /**
5372
+ * Optional `initializeBundleDepositor` + `requestDeposit`. Fetches bundle account internally.
5373
+ */
5374
+ declare function buildBundleDepositInstructions({
5375
+ bundleProgramV1,
5376
+ bundleProgramV2,
5377
+ vault,
5378
+ user,
5379
+ amount,
5380
+ needsInit
5381
+ }: BuildBundleDepositInstructionsParams): Promise<TransactionInstruction[]>;
5382
+ /**
5383
+ * `requestWithdrawal` only. Fetches bundle, oracle, and user bundle internally.
5384
+ */
5385
+ declare function buildBundleRequestWithdrawInstruction({
5386
+ bundleProgramV1,
5387
+ bundleProgramV2,
5388
+ vault,
5389
+ user,
5390
+ amount
5391
+ }: BuildBundleRequestWithdrawInstructionParams): Promise<TransactionInstruction>;
5392
+ //#endregion
5314
5393
  //#region src/utils/pda.d.ts
5315
5394
  /**
5316
5395
  * Derive Oracle PDA for Bundle vault
@@ -5320,10 +5399,18 @@ declare function deriveOraclePDA(bundlePDA: PublicKey, programId: PublicKey): Pu
5320
5399
  * Derive User PDA for Bundle vault
5321
5400
  */
5322
5401
  declare function deriveUserPDA(userKey: PublicKey, bundlePDA: PublicKey, programId: PublicKey): PublicKey;
5402
+ /**
5403
+ * Derive Temp Data PDA for Bundle vault
5404
+ */
5405
+ declare function deriveTempDataPDA(bundlePDA: PublicKey, programId: PublicKey): PublicKey;
5406
+ /**
5407
+ * Derive pending bundle asset authority PDA (pending deposit token ATA owner)
5408
+ */
5409
+ declare function derivePendingAuthPDA(bundlePDA: PublicKey, programId: PublicKey): PublicKey;
5323
5410
  /**
5324
5411
  * Get Vault Depositor PDA for Drift vault
5325
5412
  * Custom code to handle jlpdnv1 special case
5326
5413
  */
5327
5414
  declare function getVaultDepositorAddressSync(programId: PublicKey, vault: PublicKey, authority: PublicKey): PublicKey;
5328
5415
  //#endregion
5329
- export { type BundleAccount, BundleProgramId, NeutralTrade, type NeutralTradeConfig, type NeutralTradeCoreContext, type OracleData, type PointsVaultEntry, SupportedChain, SupportedToken, type Token, type UserBalanceResult, type UserBundleAccount, type UserBundleTempData, type VaultBalanceData, VaultCategory, type VaultRegistryEntry as VaultConfig, type VaultRegistry as VaultConfigRecord, VaultId, VaultType, createAnchorProviderV29, createAnchorProviderV32, createBundleProgramV1, createBundleProgramV2, createBundlePrograms, createConnection, createDummyWallet, deriveOraclePDA, deriveUserPDA, estimatePendingBundleFeeToken, getBundleProgramId, getPointsVaults, getVaultByAddress, getVaultById, getVaultDepositorAddressSync, isValidVaultAddress, tokens, vaults$1 as vaults };
5416
+ export { type BuildBundleDepositInstructionsParams, type BuildBundleRequestWithdrawInstructionParams, type BundleAccount, BundleProgramId, NeutralTrade, type NeutralTradeConfig, type NeutralTradeCoreContext, type OracleData, type PointsVaultEntry, SupportedChain, SupportedToken, type Token, type UserBalanceResult, type UserBundleAccount, type UserBundleTempData, type VaultBalanceData, VaultCategory, type VaultRegistryEntry as VaultConfig, type VaultRegistry as VaultConfigRecord, VaultId, VaultType, buildBundleDepositInstructions, buildBundleRequestWithdrawInstruction, computeRequestWithdrawalSharesAmount, createAnchorProviderV29, createAnchorProviderV32, createBundleProgramV1, createBundleProgramV2, createBundlePrograms, createConnection, createDummyWallet, deriveOraclePDA, derivePendingAuthPDA, deriveTempDataPDA, deriveUserPDA, estimatePendingBundleFeeToken, getBundleProgramId, getPointsVaults, getVaultByAddress, getVaultById, getVaultDepositorAddressSync, isValidVaultAddress, tokens, vaults$1 as vaults };
package/dist/index.mjs CHANGED
@@ -1,7 +1,8 @@
1
- import { AnchorProvider, Program } from "@coral-xyz/anchor";
1
+ import { AnchorProvider, BN, Program } from "@coral-xyz/anchor";
2
2
  import { AnchorProvider as AnchorProvider$1, Program as Program$1 } from "@coral-xyz/anchor-32";
3
- import { Connection, Keypair, PublicKey } from "@solana/web3.js";
3
+ import { Connection, Keypair, PublicKey, SYSVAR_RENT_PUBKEY, SystemProgram } from "@solana/web3.js";
4
4
  import { z } from "zod";
5
+ import { TOKEN_PROGRAM_ID, getAssociatedTokenAddressSync } from "@solana/spl-token";
5
6
 
6
7
  //#region src/constants/addr.ts
7
8
  const ZERO_ADDRESS = new PublicKey("11111111111111111111111111111111");
@@ -9372,6 +9373,20 @@ function deriveUserPDA(userKey, bundlePDA, programId) {
9372
9373
  return pda;
9373
9374
  }
9374
9375
  /**
9376
+ * Derive Temp Data PDA for Bundle vault
9377
+ */
9378
+ function deriveTempDataPDA(bundlePDA, programId) {
9379
+ const [pda] = PublicKey.findProgramAddressSync([SEED_TEMP, bundlePDA.toBuffer()], programId);
9380
+ return pda;
9381
+ }
9382
+ /**
9383
+ * Derive pending bundle asset authority PDA (pending deposit token ATA owner)
9384
+ */
9385
+ function derivePendingAuthPDA(bundlePDA, programId) {
9386
+ const [pda] = PublicKey.findProgramAddressSync([SEED_PENDING_AUTH, bundlePDA.toBuffer()], programId);
9387
+ return pda;
9388
+ }
9389
+ /**
9375
9390
  * Get Vault Depositor PDA for Drift vault
9376
9391
  * Custom code to handle jlpdnv1 special case
9377
9392
  */
@@ -9560,6 +9575,137 @@ async function getBundleBalances({ vaultIds, userAddress, vaults: vaults$1, bund
9560
9575
  return result;
9561
9576
  }
9562
9577
 
9578
+ //#endregion
9579
+ //#region src/utils/bundle-instructions.ts
9580
+ /** Same share math as legacy app `useBundleRequestWithdrawMutation`. */
9581
+ function computeRequestWithdrawalSharesAmount({ amount, userVaultBalance, pps, assetDecimals, userShares }) {
9582
+ let sharesAmount;
9583
+ if (Number(amount) >= Number(userVaultBalance)) sharesAmount = userShares;
9584
+ else sharesAmount = new BN(Math.floor(amount * 10 ** assetDecimals / pps));
9585
+ return sharesAmount.lte(userShares) ? sharesAmount : userShares;
9586
+ }
9587
+ function assertBundleVault(vault) {
9588
+ if (vault.type !== VaultType.Bundle) throw new Error(`Vault ${vault.vaultId} is not a Bundle vault`);
9589
+ }
9590
+ function bundleProgramIdForVault(vault) {
9591
+ const id = getBundleProgramId(vault);
9592
+ if (!id) throw new Error(`Vault ${vault.vaultId} has no Bundle program id`);
9593
+ return id;
9594
+ }
9595
+ /**
9596
+ * Optional `initializeBundleDepositor` + `requestDeposit`. Fetches bundle account internally.
9597
+ */
9598
+ async function buildBundleDepositInstructions({ bundleProgramV1, bundleProgramV2, vault, user, amount, needsInit = false }) {
9599
+ assertBundleVault(vault);
9600
+ const bundlePDA = new PublicKey(vault.vaultAddress);
9601
+ const isV2 = bundleProgramIdForVault(vault) === BundleProgramId.V2;
9602
+ const bundleInfo = isV2 ? await bundleProgramV2.account.bundle.fetch(bundlePDA) : await bundleProgramV1.account.bundle.fetch(bundlePDA);
9603
+ const depositAmountBN = new BN(Math.floor(amount * 10 ** bundleInfo.assetDecimals));
9604
+ const programPk = isV2 ? bundleProgramV2.programId : bundleProgramV1.programId;
9605
+ const oraclePDA = deriveOraclePDA(bundlePDA, programPk);
9606
+ const userPDA = deriveUserPDA(user, bundlePDA, programPk);
9607
+ const tempDataPDA = deriveTempDataPDA(bundlePDA, programPk);
9608
+ const pendingAuthPDA = derivePendingAuthPDA(bundlePDA, programPk);
9609
+ const userTokenAcct = getAssociatedTokenAddressSync(bundleInfo.assetAddress, user, true);
9610
+ const pendingTokenAcct = getAssociatedTokenAddressSync(bundleInfo.assetAddress, pendingAuthPDA, true);
9611
+ const instructions$2 = [];
9612
+ if (needsInit) {
9613
+ const initIx = isV2 ? await bundleProgramV2.methods.initializeBundleDepositor().accounts({
9614
+ payer: user,
9615
+ authority: user,
9616
+ systemProgram: SystemProgram.programId,
9617
+ bundleAccount: bundlePDA,
9618
+ userBundleAccount: userPDA
9619
+ }).instruction() : await bundleProgramV1.methods.initializeBundleDepositor().accounts({
9620
+ payer: user,
9621
+ authority: user,
9622
+ systemProgram: SystemProgram.programId,
9623
+ bundleAccount: bundlePDA,
9624
+ userBundleAccount: userPDA
9625
+ }).instruction();
9626
+ instructions$2.push(initIx);
9627
+ }
9628
+ const depositIx = isV2 ? await bundleProgramV2.methods.requestDeposit(depositAmountBN).accounts({
9629
+ user,
9630
+ userTokenAccount: userTokenAcct,
9631
+ pendingDepositTokenAccount: pendingTokenAcct,
9632
+ treasuryAccount: bundleInfo.treasuryAccount,
9633
+ userBundleAccount: userPDA,
9634
+ assetAddress: bundleInfo.assetAddress,
9635
+ oracleData: oraclePDA,
9636
+ bundleTempData: tempDataPDA,
9637
+ bundleAccount: bundlePDA,
9638
+ pendingBundleAssetAuthority: pendingAuthPDA,
9639
+ tokenProgram: TOKEN_PROGRAM_ID,
9640
+ systemProgram: SystemProgram.programId
9641
+ }).instruction() : await bundleProgramV1.methods.requestDeposit(depositAmountBN).accounts({
9642
+ user,
9643
+ userTokenAccount: userTokenAcct,
9644
+ pendingDepositTokenAccount: pendingTokenAcct,
9645
+ treasuryAccount: bundleInfo.treasuryAccount,
9646
+ userBundleAccount: userPDA,
9647
+ assetAddress: bundleInfo.assetAddress,
9648
+ oracleData: oraclePDA,
9649
+ bundleTempData: tempDataPDA,
9650
+ bundleAccount: bundlePDA,
9651
+ pendingBundleAssetAuthority: pendingAuthPDA,
9652
+ tokenProgram: TOKEN_PROGRAM_ID,
9653
+ systemProgram: SystemProgram.programId
9654
+ }).instruction();
9655
+ instructions$2.push(depositIx);
9656
+ return instructions$2;
9657
+ }
9658
+ /**
9659
+ * `requestWithdrawal` only. Fetches bundle, oracle, and user bundle internally.
9660
+ */
9661
+ async function buildBundleRequestWithdrawInstruction({ bundleProgramV1, bundleProgramV2, vault, user, amount }) {
9662
+ assertBundleVault(vault);
9663
+ const bundlePDA = new PublicKey(vault.vaultAddress);
9664
+ const isV2 = bundleProgramIdForVault(vault) === BundleProgramId.V2;
9665
+ const programPk = isV2 ? bundleProgramV2.programId : bundleProgramV1.programId;
9666
+ const oraclePDA = deriveOraclePDA(bundlePDA, programPk);
9667
+ const userPDA = deriveUserPDA(user, bundlePDA, programPk);
9668
+ const tempDataPDA = deriveTempDataPDA(bundlePDA, programPk);
9669
+ const [bundleAccount, oracleData, userBundle] = await Promise.all([
9670
+ isV2 ? bundleProgramV2.account.bundle.fetch(bundlePDA) : bundleProgramV1.account.bundle.fetch(bundlePDA),
9671
+ isV2 ? bundleProgramV2.account.oracleData.fetch(oraclePDA) : bundleProgramV1.account.oracleData.fetch(oraclePDA),
9672
+ isV2 ? bundleProgramV2.account.userBundleAccount.fetch(userPDA) : bundleProgramV1.account.userBundleAccount.fetch(userPDA)
9673
+ ]);
9674
+ const pps = calculateOnChainPps({
9675
+ oracleAverageExternalEquity: BigInt(oracleData.averageExternalEquity.toString()),
9676
+ bundleUnderlyingBalance: BigInt(bundleAccount.bundleUnderlyingBalance.toString()),
9677
+ totalShares: BigInt(bundleAccount.totalShares.toString())
9678
+ });
9679
+ const divisor = 10 ** bundleAccount.assetDecimals;
9680
+ const userSharesNum = Number(userBundle.shares.toString());
9681
+ const sharesAmount = computeRequestWithdrawalSharesAmount({
9682
+ amount,
9683
+ userVaultBalance: Math.round(userSharesNum * pps) / divisor,
9684
+ pps,
9685
+ assetDecimals: bundleAccount.assetDecimals,
9686
+ userShares: new BN(userBundle.shares.toString())
9687
+ });
9688
+ return isV2 ? await bundleProgramV2.methods.requestWithdrawal(sharesAmount).accounts({
9689
+ user,
9690
+ userBundleAccount: userPDA,
9691
+ bundleAccount: bundlePDA,
9692
+ oracleData: oraclePDA,
9693
+ bundleTempData: tempDataPDA,
9694
+ tokenProgram: TOKEN_PROGRAM_ID,
9695
+ systemProgram: SystemProgram.programId,
9696
+ rent: SYSVAR_RENT_PUBKEY
9697
+ }).instruction() : await bundleProgramV1.methods.requestWithdrawal(sharesAmount).accounts({
9698
+ user,
9699
+ userBundleAccount: userPDA,
9700
+ bundleAccount: bundlePDA,
9701
+ oracleData: oraclePDA,
9702
+ bundleTempData: tempDataPDA,
9703
+ tokenProgram: TOKEN_PROGRAM_ID,
9704
+ systemProgram: SystemProgram.programId,
9705
+ rent: SYSVAR_RENT_PUBKEY
9706
+ }).instruction();
9707
+ }
9708
+
9563
9709
  //#endregion
9564
9710
  //#region src/utils/price.ts
9565
9711
  /**
@@ -9705,7 +9851,36 @@ var NeutralTrade = class NeutralTrade {
9705
9851
  priceMap: this.priceMap
9706
9852
  });
9707
9853
  }
9854
+ /**
9855
+ * Build deposit instructions (optional init + requestDeposit). Fetches vault state on-chain.
9856
+ */
9857
+ async buildDepositInstructions({ vaultId, userAddress, amount, needsInit = false }) {
9858
+ const vault = this.vaults[vaultId];
9859
+ if (!vault) throw new Error(`Vault config not found for vaultId ${vaultId}`);
9860
+ return buildBundleDepositInstructions({
9861
+ bundleProgramV1: this.bundleProgramV1,
9862
+ bundleProgramV2: this.bundleProgramV2,
9863
+ vault,
9864
+ user: new PublicKey(userAddress),
9865
+ amount,
9866
+ needsInit
9867
+ });
9868
+ }
9869
+ /**
9870
+ * Build request-withdraw instruction. Fetches vault, oracle, and depositor accounts on-chain.
9871
+ */
9872
+ async buildRequestWithdrawInstruction({ vaultId, userAddress, amount }) {
9873
+ const vault = this.vaults[vaultId];
9874
+ if (!vault) throw new Error(`Vault config not found for vaultId ${vaultId}`);
9875
+ return buildBundleRequestWithdrawInstruction({
9876
+ bundleProgramV1: this.bundleProgramV1,
9877
+ bundleProgramV2: this.bundleProgramV2,
9878
+ vault,
9879
+ user: new PublicKey(userAddress),
9880
+ amount
9881
+ });
9882
+ }
9708
9883
  };
9709
9884
 
9710
9885
  //#endregion
9711
- export { BundleProgramId, NeutralTrade, SupportedChain, SupportedToken, VaultCategory, VaultId, VaultType, createAnchorProviderV29, createAnchorProviderV32, createBundleProgramV1, createBundleProgramV2, createBundlePrograms, createConnection, createDummyWallet, deriveOraclePDA, deriveUserPDA, estimatePendingBundleFeeToken, getBundleProgramId, getPointsVaults, getVaultByAddress, getVaultById, getVaultDepositorAddressSync, isValidVaultAddress, tokens, vaults };
9886
+ export { BundleProgramId, NeutralTrade, SupportedChain, SupportedToken, VaultCategory, VaultId, VaultType, buildBundleDepositInstructions, buildBundleRequestWithdrawInstruction, computeRequestWithdrawalSharesAmount, createAnchorProviderV29, createAnchorProviderV32, createBundleProgramV1, createBundleProgramV2, createBundlePrograms, createConnection, createDummyWallet, deriveOraclePDA, derivePendingAuthPDA, deriveTempDataPDA, deriveUserPDA, estimatePendingBundleFeeToken, getBundleProgramId, getPointsVaults, getVaultByAddress, getVaultById, getVaultDepositorAddressSync, isValidVaultAddress, tokens, vaults };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@neutral-trade/sdk",
3
3
  "type": "module",
4
- "version": "0.2.3",
4
+ "version": "0.2.5",
5
5
  "description": "SDK for Neutral Trade vaults",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/neutral-trade/sdk#readme",
@@ -25,6 +25,7 @@
25
25
  "dependencies": {
26
26
  "@coral-xyz/anchor": "0.29.0",
27
27
  "@coral-xyz/anchor-32": "npm:@coral-xyz/anchor@0.32.0",
28
+ "@solana/spl-token": "^0.4.14",
28
29
  "@solana/web3.js": "^1.98.4",
29
30
  "@types/bn.js": "^5.2.0",
30
31
  "bn.js": "^5.2.3",