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

how to calculator solana fee without rpc? #251

Open
BillInUK opened this issue Oct 18, 2024 · 0 comments
Open

how to calculator solana fee without rpc? #251

BillInUK opened this issue Oct 18, 2024 · 0 comments

Comments

@BillInUK
Copy link

i send an transaction to trasfer my spl token,in the following code i simulate my transaction to get the comsumed units,and GetFeeForMessage to calculate the transaction fee.

func TestEstimateMultiTransferFee(t *testing.T) {
	fromPrivateKey, _ := solana.PrivateKeyFromSolanaKeygenFile("/Users/mac/.config/solana/priv_alice.json")
	fromNativeAccount := fromPrivateKey.PublicKey()
	toNativeAccounts := []solana.PublicKey{
		solana.MPK("27htRMGeQ4HV32SPHsJrpndZn1zwmF2kiPqmABcHgehx"),
	}
	tokenMintAccount := solana.MPK(TokenMintAddress)
	var amount uint64 = 1000
	var decimals uint8 = 3
	priorityFee, err := querySOLPriorityFee()
	if err != nil {
		panic(err)
	}
	var transferInsts []solana.Instruction
	for index, _ := range toNativeAccounts {
		fromTokenAccount, _, _ := solana.FindAssociatedTokenAddress(fromNativeAccount, tokenMintAccount)
		toTokenAccount, _, _ := solana.FindAssociatedTokenAddress(toNativeAccounts[index], tokenMintAccount)
		inst := token.NewTransferCheckedInstructionBuilder().
			SetAmount(amount).
			SetDecimals(decimals).
			SetSourceAccount(fromTokenAccount).
			SetMintAccount(tokenMintAccount).
			SetDestinationAccount(toTokenAccount).
			SetOwnerAccount(fromNativeAccount).
			Build()
		transferInsts = append(transferInsts, inst)
	}

	// 构造1笔交易用来评估手续费
	computePrice := priorityFee.PerTransaction.Medium
	computeBudgetPriceInst := computebudget.NewSetComputeUnitPriceInstructionBuilder().SetMicroLamports(computePrice).Build()
	var simulateInstructions []solana.Instruction
	simulateInstructions = append(simulateInstructions, computeBudgetPriceInst)
	simulateInstructions = append(simulateInstructions, transferInsts...)

	recent, err := rpcClient.GetLatestBlockhash(context.Background(), rpc.CommitmentFinalized)
	if err != nil {
		panic(err)
	}

	// simulate执行交易
	simulateSolTx, err := solana.NewTransaction(simulateInstructions, recent.Value.Blockhash, solana.TransactionPayer(fromNativeAccount))
	if err != nil {
		panic(err)
	}
	msgBin, _ := simulateSolTx.Message.MarshalBinary()
	fromSign, _ := fromPrivateKey.Sign(msgBin)
	simulateSolTx.Signatures = append(simulateSolTx.Signatures, fromSign)
	simulateResult, err := rpcClient.SimulateTransactionWithOpts(context.Background(), simulateSolTx, &rpc.SimulateTransactionOpts{
		ReplaceRecentBlockhash: true,
	})
	if err != nil {
		panic(err)
	}
	computeUnits := uint32(*simulateResult.Value.UnitsConsumed)
	computeBudgetLimitInst := computebudget.NewSetComputeUnitLimitInstructionBuilder().SetUnits(computeUnits).Build()
	simulateInstructions = append(simulateInstructions, computeBudgetLimitInst)

	fmt.Printf("computeUnitPrice %d\n", computePrice)
	fmt.Printf("computeUnitLimit %d\n", computeUnits)

	// 获取手续费
	base64EncodeMsg := base64.StdEncoding.EncodeToString(msgBin)
	fee, err := rpcClient.GetFeeForMessage(context.Background(), base64EncodeMsg, rpc.CommitmentFinalized)
	if err != nil {
		panic(err)
	}
	if fee == nil || *fee.Value == 0 {
		panic("estimate fee returns 0")
	}
	fmt.Printf("estimate fee %d\n", *fee.Value)

	txId, err := rpcClient.SendTransactionWithOpts(context.Background(), simulateSolTx, rpc.TransactionOpts{SkipPreflight: true})
	if err != nil {
		panic(err)
	} else {
		fmt.Printf("%s\n", txId.String())
		fmt.Printf("https://explorer.solana.com/tx/%s?cluster=devnet\n", txId.String())
	}

}

the output of the code is :

computeUnitPrice 50003
computeUnitLimit 6322
estimate fee 15001
2jUhRghTdtZ3pwszNK868njTWdke3V7zPikbYHzbNqMxdnjGR1PPbGJSomek7PMcnVKKmz3UxMJJdVEFPijaSvhG
https://explorer.solana.com/tx/2jUhRghTdtZ3pwszNK868njTWdke3V7zPikbYHzbNqMxdnjGR1PPbGJSomek7PMcnVKKmz3UxMJJdVEFPijaSvhG?cluster=devnet
--- PASS: TestEstimateMultiTransferFee (2.38s)
PASS

I followed Solana's official method for calculating transaction fees, but I am unable to get a result of 15001. Could you please explain how the fee of 15001 was calculated?

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

1 participant