solanasolana-web3js

How do I "unwrap SOL" using the web3 sdk?


I need to unwrap some SOL using the web3 sdk. I'm wondering, Is it just a simple transfer from the wrapped account into SOL account or is it more complicated than that? Below Is just some sample code I've setup.

const emptyWSolAccount = async (amount:any) => {
  const wsolAddress = await Token.getAssociatedTokenAddress(
    ASSOCIATED_TOKEN_PROGRAM_ID,
    TOKEN_PROGRAM_ID,
    new PublicKey("So11111111111111111111111111111111111111112"),
    wallet.publicKey
  );

  const wsolAccount = await connection.getAccountInfo(wsolAddress);

  if (wsolAccount) {
    const transaction = new Transaction({
      feePayer: wallet.publicKey,
    });
    const instructions = [];

    const lamports = amount * LAMPORTS_PER_SOL;
    
    instructions.push(
      SystemProgram.transfer({
        fromPubkey: wsolAddress,
        toPubkey: wallet.publicKey,
        lamports: lamports, // 1 sol
      })
    );

    transaction.add(...instructions);
    transaction.recentBlockhash = await (
      await connection.getRecentBlockhash()
    ).blockhash;
    transaction.partialSign(wallet.payer);
    const result = await connection.sendTransaction(transaction, [
      wallet.payer,
    ]);
    console.log({ result });
    return { result };
  }

  return ;
};

Solution

  • This is not really explained anywhere, but unwrapping SOL actually means closing the wrapped SOL account.

    So instead of using a SystemProgram.transfer instruction, you'll do:

        instructions.push(
          splToken.instructions.createCloseAccountInstruction(
            wsolAddress,
            wallet.publicKey,
            wallet.publicKey,
          )
        );
    

    This closes wsolAddress and sends the contents to wallet, assuming that wallet is the owner.

    You can see the CLI implementation at https://github.com/solana-labs/solana-program-library/blob/3db53e278b543a040d3c970797b6be6f9ea5aef9/token/cli/src/main.rs#L1139-L1194