-
Notifications
You must be signed in to change notification settings - Fork 323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How do I transfer tokens #71
Comments
Old question but could be useful to someone import (
"context"
"fmt"
"math"
"strconv"
"github.com/gagliardetto/solana-go"
associatedtokenaccount "github.com/gagliardetto/solana-go/programs/associated-token-account"
"github.com/gagliardetto/solana-go/programs/token"
"github.com/gagliardetto/solana-go/rpc"
)
func tokenTransfer(sender solana.PrivateKey, receiver solana.PublicKey, tokenMint solana.PublicKey) (solana.Signature, error) {
httpClient := rpc.New(rpc.DevNet_RPC)
ixs := []solana.Instruction{}
tokenAta := solana.PublicKey{}
//get list of ata associated to the token mint address
atas, err := httpClient.GetTokenAccountsByOwner(
context.TODO(),
receiver,
&rpc.GetTokenAccountsConfig{
Mint: &tokenMint,
},
&rpc.GetTokenAccountsOpts{})
//create new ata if none found
if err != nil || len(atas.Value) == 0 {
if err != nil {
panic(err)
}
ix, err := associatedtokenaccount.NewCreateInstruction(
sender.PublicKey(),
receiver,
tokenMint).ValidateAndBuild()
if err != nil {
panic(err)
}
ixs = append(ixs, ix)
tokenAta = ix.Accounts()[1].PublicKey
} else {
//if token atas found i just get the first one
tokenAta = atas.Value[0].Pubkey
}
//transfer instruction
amount := uint64(10 * math.Pow10(9)) //Sending n10 tokens of a token that has 9 decimals
fromAccountAtas, err := httpClient.GetTokenAccountsByOwner(
context.TODO(),
sender.PublicKey(),
&rpc.GetTokenAccountsConfig{
Mint: &tokenMint,
},
&rpc.GetTokenAccountsOpts{})
if err != nil {
panic(err)
}
if len(fromAccountAtas.Value) == 0 {
panic(fmt.Errorf("sender does not have any tokens"))
}
//get sender wallet token ata + check if sender have enough tokens
fromAccountAta := solana.PublicKey{}
hasEnoughTokens := true
for _, ata := range fromAccountAtas.Value {
hasEnoughTokens = true
balance, err := httpClient.GetTokenAccountBalance(context.TODO(), ata.Pubkey, rpc.CommitmentFinalized)
if err != nil {
continue
}
a, err := strconv.ParseUint(balance.Value.Amount, 10, 64)
if err != nil {
continue
}
if a < amount {
hasEnoughTokens = false
continue
}
fromAccountAta = ata.Pubkey
break
}
if fromAccountAta == solana.SystemProgramID {
if !hasEnoughTokens {
err = fmt.Errorf("sender does not have enough tokens")
}
panic(err)
}
//transfer instruction
ix := token.NewTransferInstruction(
amount,
fromAccountAta,
tokenAta,
sender.PublicKey(),
[]solana.PublicKey{}).Build()
ixs = append(ixs, ix)
recentBlockHash, err := httpClient.GetRecentBlockhash(context.TODO(), rpc.CommitmentFinalized)
if err != nil {
panic(err)
}
tx, err := solana.NewTransaction(
ixs,
recentBlockHash.Value.Blockhash,
solana.TransactionPayer(sender.PublicKey()),
)
if err != nil {
panic(err)
}
//sign transaction
_, err = tx.Sign(
func(key solana.PublicKey) *solana.PrivateKey {
if sender.PublicKey().Equals(key) {
return &sender
}
return nil
},
)
if err != nil {
panic(err)
}
//send transaction
sig, err := httpClient.SendTransaction(
context.TODO(),
tx,
)
if err != nil {
panic(err)
}
// send transaction and wait for confirmation
// import confirm "github.com/gagliardetto/solana-go/rpc/sendAndConfirmTransaction"
// sig, err := confirm.SendAndConfirmTransaction(
// context.TODO(),
// httpClient,
// wsClient,
// tx,
// )
return sig, nil
} |
doesnt work for me |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Is there a way that I can use this library to send tokens from one wallet to another?
If so please tell me where.
The text was updated successfully, but these errors were encountered: