0x0x230x

Untitled

Feb 24th, 2026
49
0
Never
7
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.07 KB | None | 0 0
  1. 'use client';
  2.  
  3. import { Program } from '@coral-xyz/anchor';
  4. import { useConnectorClient, useTransactionSigner } from '@solana/connector';
  5. import {
  6. ASSOCIATED_TOKEN_PROGRAM_ID,
  7. createAssociatedTokenAccountInstruction,
  8. createSyncNativeInstruction,
  9. getAssociatedTokenAddressSync,
  10. NATIVE_MINT,
  11. TOKEN_PROGRAM_ID,
  12. } from '@solana/spl-token';
  13. import {
  14. Connection,
  15. PublicKey,
  16. SystemProgram,
  17. Transaction,
  18. type TransactionInstruction,
  19. } from '@solana/web3.js';
  20. import { useMutation } from '@tanstack/react-query';
  21. import BN from 'bn.js';
  22. import { useCallback } from 'react';
  23.  
  24. import { YOSOL_FEE_RECIPIENT } from '@/lib/config/vaults/solana/config';
  25. import type { YoVault } from '@/lib/config/vaults/solana/yo-vault-sol';
  26. import yoVaultSolIdl from '@/lib/config/vaults/solana/yo-vault-sol.json';
  27.  
  28. type SolanaVaultAddresses = {
  29. tokenMint: string; // vault.asset.address
  30. shareMint: string; // vault.shareAsset.address
  31. };
  32.  
  33. type DepositResult = {
  34. signature: string;
  35. confirmed: boolean;
  36. };
  37.  
  38. /**
  39. * Hook for depositing SOL into a Solana vault.
  40. *
  41. * Flow:
  42. * 1. Wrap SOL to WSOL (create ATA if needed, transfer SOL, sync native)
  43. * 2. Call vault deposit instruction via Anchor
  44. * 3. Sign and send transaction via ConnectorKit
  45. *
  46. * @param addresses - Vault addresses from backend vault data
  47. * @param enabled - Whether the hook should be active (use false for EVM vaults)
  48. */
  49. export function useSolanaDeposit(addresses: SolanaVaultAddresses | null, enabled = true) {
  50. const { signer, ready, address: walletAddress } = useTransactionSigner();
  51. const client = useConnectorClient();
  52.  
  53. const mutation = useMutation({
  54. mutationFn: async (amountLamports: bigint): Promise<DepositResult> => {
  55. if (!signer || !walletAddress) {
  56. throw new Error('Wallet not connected');
  57. }
  58. if (!addresses) {
  59. throw new Error('Vault addresses not available');
  60. }
  61.  
  62. // Get RPC URL from connector client
  63. const rpcUrl = client?.getRpcUrl();
  64. if (!rpcUrl) {
  65. throw new Error('No RPC endpoint configured');
  66. }
  67.  
  68. const connection = new Connection(rpcUrl, 'confirmed');
  69. const walletPubkey = new PublicKey(walletAddress);
  70. const amountBN = new BN(amountLamports.toString());
  71.  
  72. const tokenMint = new PublicKey(addresses.tokenMint);
  73. const shareMint = new PublicKey(addresses.shareMint);
  74.  
  75. // Build wrap SOL instructions
  76. const wrapIxs = await buildWrapSolIxs(walletPubkey, amountLamports, connection);
  77.  
  78. // Build deposit instruction via Anchor
  79. const program = new Program(yoVaultSolIdl as YoVault, { connection });
  80. const depositIx = await program.methods
  81. .deposit(amountBN)
  82. .accounts({
  83. user: walletPubkey,
  84. feeRecipient: YOSOL_FEE_RECIPIENT,
  85. tokenMint,
  86. shareMint,
  87. program: program.programId,
  88. })
  89. .instruction();
  90.  
  91. // Combine instructions into transaction
  92. const allIxs = [...wrapIxs, depositIx];
  93. const tx = new Transaction().add(...allIxs);
  94. const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
  95. tx.recentBlockhash = blockhash;
  96. tx.feePayer = walletPubkey;
  97. tx.lastValidBlockHeight = lastValidBlockHeight;
  98.  
  99. // Sign and send via ConnectorKit
  100. const signature = await signer.signAndSendTransaction(tx);
  101.  
  102. return { signature, confirmed: true };
  103. },
  104. });
  105.  
  106. const reset = useCallback(() => {
  107. mutation.reset();
  108. }, [mutation]);
  109.  
  110. return {
  111. executeDeposit: mutation.mutate,
  112. executeDepositAsync: mutation.mutateAsync,
  113. isPending: mutation.isPending,
  114. isConfirming: false,
  115. isConfirmed: !!mutation.data?.signature,
  116. error: mutation.error,
  117. txSignature: mutation.data?.signature,
  118. isReady: enabled && ready && !!signer,
  119. reset,
  120. };
  121. }
  122.  
  123. /**
  124. * Build instructions to wrap SOL to WSOL.
  125. *
  126. * 1. Create WSOL ATA if it doesn't exist
  127. * 2. Transfer SOL to WSOL ATA
  128. * 3. Sync native balance to update token account balance
  129. */
  130. async function buildWrapSolIxs(
  131. user: PublicKey,
  132. lamports: bigint,
  133. connection: Connection
  134. ): Promise<TransactionInstruction[]> {
  135. const instructions: TransactionInstruction[] = [];
  136.  
  137. // Get user's WSOL ATA address
  138. const userWsolAccount = getAssociatedTokenAddressSync(NATIVE_MINT, user);
  139.  
  140. // Check if WSOL ATA exists
  141. const ataInfo = await connection.getAccountInfo(userWsolAccount);
  142. if (!ataInfo) {
  143. instructions.push(
  144. createAssociatedTokenAccountInstruction(
  145. user,
  146. userWsolAccount,
  147. user,
  148. NATIVE_MINT,
  149. TOKEN_PROGRAM_ID,
  150. ASSOCIATED_TOKEN_PROGRAM_ID
  151. )
  152. );
  153. }
  154.  
  155. // Transfer SOL to WSOL account
  156. instructions.push(
  157. SystemProgram.transfer({
  158. fromPubkey: user,
  159. toPubkey: userWsolAccount,
  160. lamports,
  161. })
  162. );
  163.  
  164. // Sync native balance to update token account balance
  165. instructions.push(createSyncNativeInstruction(userWsolAccount, TOKEN_PROGRAM_ID));
  166.  
  167. return instructions;
  168. }
  169.  
  170. export default useSolanaDeposit;
  171.  
Advertisement
Comments
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
Add Comment
Please, Sign In to add comment