Reputation: 351
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
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