gagliardetto / solana-go

Go SDK library and RPC client for the Solana Blockchain
Apache License 2.0
818 stars 243 forks source link

Send SPL Token using this Library #200

Closed metarsit closed 4 months ago

metarsit commented 5 months ago

About

I am trying to figure out how to send SPL tokens (e.g., WIF).

Current Code to send SOL

    tx, err := solana.NewTransaction(
        []solana.Instruction{
            feesInit.Build(),
            limit.Build(),
            system.NewTransferInstruction(
                bigAmt.Uint64(),
                accountFrom.PublicKey(),
                accountTo,
            ).Build(),
        },
        recent,
        solana.TransactionPayer(accountFrom.PublicKey()),
    )
    if err != nil {
        return errors.Wrap(err, "unable to create new transaction")
    }

This is how I currently craft up the transactions for sending SOL with a priority fee.

However, things get tricky when I am trying to work on SPL. I don't see many documentation around it and I assume it is token package?

If someone can point me to the right direction to read or to the file I should be looking at, that would be amazing!

Thank you in advance!

metarsit commented 4 months ago

Alright, I got it! 😆

// Get Source Account
sourceAccount, _, err := solana.FindAssociatedTokenAddress(from.PublicKey(), tokenContract.PublicKey())
if err != nil {
    return errors.Wrap(err, "could not find associated token account for source account")
}

// Get Destination Account
destinationAccount, _, err := solana.FindAssociatedTokenAddress(to.PublicKey(), tokenContract.PublicKey())
if err != nil {
    // This error happens when there is no associated token account for the destination account
    log.Debug("could not find associated token account for destination account", "error", err)
    // So we need to create ATP for the destination account
}

instructions = append(instructions,
    token.NewTransferCheckedInstruction(
        1,                         // Some amount
        precision,                 // Token precision
        sourceAccount,             // source (token account)
        tokenContract.PublicKey(), // mint
        destinationAccount,        // destination (token account)
        accountFrom.PublicKey()    // owner
        []solana.PublicKey{},
    ).Build(),
)

tx, err := solana.NewTransaction(
    instructions,
    recentBlockhash,
    solana.TransactionPayer(from.PublicKey()),
)
if err != nil {
    return errors.Wrap(err, "unable to create new transaction")
}

log.Info("Succeed!")

That should do it!

metarsit commented 4 months ago

@gagliardetto Should I have this as part of example ser?