Skip to content
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

Add new Instructions to already existing transactions #175

Open
Moses-Alero opened this issue Jul 7, 2024 · 2 comments
Open

Add new Instructions to already existing transactions #175

Moses-Alero opened this issue Jul 7, 2024 · 2 comments

Comments

@Moses-Alero
Copy link

I would like to know if it is possible to add new instructions to pre-existing transactions similar to transaction.add() in the @solana/web3.js package.

I tried to do something to make it work using the example below

var feePayer, _ = types.AccountFromBase58("4TMFNY9ntAn3CHzguSAvDNLPRoQTaK3sWbQQXdDXaE6KWRBLufGL6PJdsD2koiEe3gGmMdRK3aAw7sikGNksHJrN")

// 9aE476sH92Vz7DMPyq5WLPkrKWivxeuTKEFKd2sZZcde
var alice, _ = types.AccountFromBase58("4voSPg3tYuWbKzimpQK9EbXHmuyy5fUrtXvpLDMLkmY6TRncaTHAKGD8jUg3maB5Jbrd9CkQg4qjJMyN6sQvnEF2")

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

	// to fetch recent blockhash
	recentBlockhashResponse, err := c.GetLatestBlockhash(context.Background())
	if err != nil {
		log.Fatalf("failed to get recent blockhash, err: %v", err)
	}

	// create a transfer tx
	tx, err := types.NewTransaction(types.NewTransactionParam{
		Signers: []types.Account{feePayer, alice},
		Message: types.NewMessage(types.NewMessageParam{
			FeePayer:        feePayer.PublicKey,
			RecentBlockhash: recentBlockhashResponse.Blockhash,
			Instructions: []types.Instruction{
				system.Transfer(system.TransferParam{
					From:   alice.PublicKey,
					To:     common.PublicKeyFromString("2xNweLHLqrbx4zo1waDvgWJHgsUpPj8Y8icbAFeR4a8i"),
					Amount: 1e8, // 0.1 SOL
				}),
			},
		}),
	})
	if err != nil {
		log.Fatalf("failed to new a transaction, err: %v", err)
	}
	//new instruction
	newInstruction := system.Transfer(system.TransferParam{
		From:   alice.PublicKey,
		To:     common.PublicKeyFromString("2xNweLHLqrbx4zo1waDvgWJHgsUpPj8Y8icbAFeR4a8i"),
		Amount: 1e8, // 0.1 SOL
	})

	//add new instruction to pre-existing Transaction
	msg := types.NewMessage(types.NewMessageParam{
		Instructions: []types.Instruction{newInstruction},
	})
	msgByte, _ := msg.Serialize()

	newMsg, _ := types.MessageDeserialize(msgByte)
	
	tx.Message.Instructions = append(tx.Message.Instructions, newMsg.Instructions...)

        //get transaction hash
	txhash, err := c.SendTransaction(context.Background(), tx)
	if err != nil {
		log.Fatalf("failed to send tx, err: %v", err)
	}

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

I tried to make it work using the example above.
It returns tx hash but the second instruction isn't added to the transaction when viewed on the explorar
Is there a way to do this?

@yihau
Copy link
Collaborator

yihau commented Jul 8, 2024

your example might not work. tx.Message.Instructions is compiled instruction. you need the same account list to generate a correct compiled instruction. we can do something similar to transaction.add() by this SDK but it's a bit tricky atm. could you provide more details about your scenario? does it help if you pass the instructions instead then compose them into a transaction in the finial step?

@Moses-Alero
Copy link
Author

@yihau my current use case requires the transaction to be passed in as an argument to a function then an additional instruction which is the new instruction is then added to the transaction before it is then used.
Here's a simple example

func CreatePostRes(tx types.Transaction, ref common.PublicKey){
     //do simple check
     if len(tx.Message.Instruction) < 1 {
        return
     }
     instruction := fetchNewInstruction(ref)
     
     //append instruction to tx
     
     tx = AddIxToTransaction(tx, instruction) //we do the tricky stuff here
   
   ...
}

Something like the above.

If only there was a way to decompile instructions then compile them back with the data intact. I think that might be helpful too.
you said that doing something similar to transaction.add() is possible but tricky. I'm pretty sure I can handle tricky :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants