gagliardetto / solana-go

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

invalid transaction: Transaction failed to sanitize accounts offsets correctly #186

Closed ubuygold closed 7 months ago

ubuygold commented 7 months ago

I'm developing a program with Jupiter Api and gagliardetto/solana-go. It always returns invalid transaction: Transaction failed to sanitize accounts offsets correctly when I submit the transaction. And both two of the Privatekeys(the payer key and the base(order id) key) are used to sign the transaction.

My code like below:

func (s *RaydiumSwap) MakeLimitSellOrder(ctx context.Context, tokenMint string, inAmount uint64, outAmount uint64) (*solana.Signature, error) {
    fromToken := tokenMint
    toToken := config.WrappedSOL

        // Unique Order ID of Jup limit order
    base := solana.NewWallet()

    resp, err := s.GetTxInfo(inAmount, fromToken, outAmount, toToken, base.PublicKey().String())
    if err != nil {
        return nil, err
    }

    tx, err := NewTransactionFromBase64(resp)
    if err != nil {
        return nil, err
    }

    signers := []solana.PrivateKey{*&s.account, *&base.PrivateKey}

    _, err = tx.Sign(
        func(key solana.PublicKey) *solana.PrivateKey {
            for _, signer := range signers {
           if signer.PublicKey().Equals(key) {
           return &signer 
           }

            }
         log.Println("Missing Key: ", key)
        return nil 
        },
    )

    if err != nil {
        return nil, err
    }

    rawTransaction, err := tx.MarshalBinary()
    if err != nil {
        return nil, err
    }

    log.Println(tx.MustToBase64())

    sig, err := s.clientRPC.SendRawTransactionWithOpts(
        ctx,
        rawTransaction,
        rpc.TransactionOpts{
            SkipPreflight:       false,
            PreflightCommitment: rpc.CommitmentFinalized,
        },
    )

    if err != nil {
        return nil, err
    }
    return &sig, nil
}

Doc from Jupiter are like:

Deserialize and sign the transaction


    // deserialize the transaction
    const transactionBuf = Buffer.from(tx, "base64");
    var transaction = VersionedTransaction.deserialize(transactionBuf);

    // sign the transaction using the required key
    // for create order, wallet and base key are required.
    transaction.sign([wallet.payer, base]);

Execute the transaction


// Execute the transaction
const rawTransaction = transaction.serialize();
const txid = await connection.sendRawTransaction(rawTransaction, {
  skipPreflight: true,
  maxRetries: 2,
});
await connection.confirmTransaction(txid);
console.log(`https://solscan.io/tx/${txid}`);
ubuygold commented 7 months ago

It seems that tx.Sign() can’t overwrite the origin signature(11111111111…) from jupiter and I have to delete them manually.