matt
matt

Reputation: 351

Solana / web3.js : getting web3.Signer from wallet

I want to send a token from one wallet to another using web3.js and spl-token. To send it I have to create an object named Token, one of the parameters of the constructor of Token() is payer: web3.Signer.

    const mintPublicKey = new web3.PublicKey(this.props.nft.data.mint);  
    const mintToken = new Token(
      this.props.connection,
      mintPublicKey,
      TOKEN_PROGRAM_ID,
      //payer: web3.Signer,
    );

I get the information from the user's wallet using @solana/wallet-adapter-wallets. I know that web3.Signer is created from a private key, which cannot be obtained from a wallet for security purpose.

I actually don't know how to deals with wallet to get the transaction done.

Thanks a lot for your help, here is my full code :

import * as web3 from "@solana/web3.js";
import { getPhantomWallet } from "@solana/wallet-adapter-wallets";
import { Token, TOKEN_PROGRAM_ID } from "@solana/spl-token";


async sendNFT() {
  const wallet = getPhantomWallet();
  const adapter = wallet.adapter();

  await adapter.connect();
  if (adapter.connected && adapter.publicKey != null)
  {
    const mintPublicKey = new web3.PublicKey(this.props.nft.data.mint);  
    const mintToken = new Token(
      this.props.connection,
      mintPublicKey,
      TOKEN_PROGRAM_ID,
      //payer: web3.Signer
    );
          
    const fromTokenAccount = await mintToken.getOrCreateAssociatedAccountInfo(
      adapter.publicKey
    );

    const destPublicKey = new web3.PublicKey("example");

    const associatedDestinationTokenAddr = await Token.getAssociatedTokenAddress(
      mintToken.associatedProgramId,
      mintToken.programId,
      mintPublicKey,
      destPublicKey
    );

    const receiverAccount = await this.props.connection.getAccountInfo(associatedDestinationTokenAddr);
          
    const instructions: web3.TransactionInstruction[] = [];  

    if (receiverAccount === null) {

      instructions.push(
        Token.createAssociatedTokenAccountInstruction(
          mintToken.associatedProgramId,
          mintToken.programId,
          mintPublicKey,
          associatedDestinationTokenAddr,
          destPublicKey,
          adapter.publicKey
        )
      )

    }
    
    instructions.push(
      Token.createTransferInstruction(
        TOKEN_PROGRAM_ID,
        fromTokenAccount.address,
        associatedDestinationTokenAddr,
        adapter.publicKey,
        [],
        1000000
      )
    );

    const transaction = new web3.Transaction().add(...instructions);
    transaction.feePayer = adapter.publicKey;
    transaction.recentBlockhash = (await this.props.connection.getRecentBlockhash()).blockhash;
    
    const transactionSignature = await this.props.connection.sendRawTransaction(
      transaction.serialize(),
      { skipPreflight: true }
    );

    await this.props.connection.confirmTransaction(transactionSignature);
  }
}

Upvotes: 4

Views: 4224

Answers (1)

DaveTheAl
DaveTheAl

Reputation: 2155

I think the easiest way to do this is to create a provider and get the signer from there.


provider = new anchor.Provider(connection, wallet, anchor.Provider.defaultOptions());
    

and then you can send transactions by invoking provider.send(tx), which will also sign with your wallet if it requires signing.

Upvotes: 0

Related Questions