Associated Token Account

Unlike a random token account, an associated token account (ATA) is calculated by SOL's address.

You can get an ATA like this

ata, _, err := common.FindAssociatedTokenAddress(alice.PublicKey, mintPubkey)
if err != nil {
	log.Fatalf("find ata error, err: %v", err)
}
fmt.Println("ata:", ata.ToBase58())

It always return the same result if you pass the same owner and mint

Then here is the instruction:

Associated Token Program

assotokenprog.CreateAssociatedTokenAccount(assotokenprog.CreateAssociatedTokenAccountParam{
	Funder:                 feePayer.PublicKey,
	Owner:                  alice.PublicKey,
	Mint:                   mintPubkey,
	AssociatedTokenAccount: ata,
}),

Funder is the person will pay the account's init balance

Owner is the owner of token account.

Mint is the mint which the token account will hold.

AssociatedTokenAccount is the result which returned by FindAssociatedTokenAddress

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/portto/solana-go-sdk/client"
	"github.com/portto/solana-go-sdk/common"
	"github.com/portto/solana-go-sdk/program/assotokenprog"
	"github.com/portto/solana-go-sdk/rpc"
	"github.com/portto/solana-go-sdk/types"
)

var feePayer, _ = types.AccountFromBytes([]byte{178, 244, 76, 4, 247, 41, 113, 40, 111, 103, 12, 76, 195, 4, 100, 123, 88, 226, 37, 56, 209, 180, 92, 77, 39, 85, 78, 202, 121, 162, 88, 29, 125, 155, 223, 107, 139, 223, 229, 82, 89, 209, 27, 43, 108, 205, 144, 2, 74, 159, 215, 57, 198, 4, 193, 36, 161, 50, 160, 119, 89, 240, 102, 184})

var alice, _ = types.AccountFromBytes([]byte{196, 114, 86, 165, 59, 177, 63, 87, 43, 10, 176, 101, 225, 42, 129, 158, 167, 43, 81, 214, 254, 28, 196, 158, 159, 64, 55, 123, 48, 211, 78, 166, 127, 96, 107, 250, 152, 133, 208, 224, 73, 251, 113, 151, 128, 139, 86, 80, 101, 70, 138, 50, 141, 153, 218, 110, 56, 39, 122, 181, 120, 55, 86, 185})

var mintPubkey = common.PublicKeyFromString("29oPCpWj6QiXEipwtmXPrDJAR2P29Z6wHKpHRxEsbnSr")

func main() {
	c := client.NewClient(rpc.LocalnetRPCEndpoint)

	ata, _, err := common.FindAssociatedTokenAddress(alice.PublicKey, mintPubkey)
	if err != nil {
		log.Fatalf("find ata error, err: %v", err)
	}
	fmt.Println("ata:", ata.ToBase58())

	res, err := c.GetRecentBlockhash(context.Background())
	if err != nil {
		log.Fatalf("get recent block hash error, err: %v\n", err)
	}
	tx, err := types.NewTransaction(types.NewTransactionParam{
		Message: types.NewMessage(types.NewMessageParam{
			FeePayer:        feePayer.PublicKey,
			RecentBlockhash: res.Blockhash,
			Instructions: []types.Instruction{
				assotokenprog.CreateAssociatedTokenAccount(assotokenprog.CreateAssociatedTokenAccountParam{
					Funder:                 feePayer.PublicKey,
					Owner:                  alice.PublicKey,
					Mint:                   mintPubkey,
					AssociatedTokenAccount: ata,
				}),
			},
		}),
		Signers: []types.Account{feePayer},
	})
	if err != nil {
		log.Fatalf("generate tx error, err: %v\n", err)
	}

	txhash, err := c.SendTransaction(context.Background(), tx)
	if err != nil {
		log.Fatalf("send raw tx error, err: %v\n", err)
	}

	log.Println("txhash:", txhash)
}

Last updated