trezor-suite icon indicating copy to clipboard operation
trezor-suite copied to clipboard

Solana: Include priority fee in TX

Open sime opened this issue 11 months ago • 1 comments

User Story

As a Solana user I want to send transactions So that I can operate within the Solana ecosystem

Acceptance Criteria

Given I sign a transaction When I broadcast it Then it should appear as confirmed

Proposal

Introduce dynamic priority fee. From user POV it will be labelled as 'fee', whilst in fact it will be the sum of the base fee and the network influenced priority fee.

nu.fi wallet has just launched priority fee support.

Background

Solana has entered a high fee environment and the default base fee of 0.000005 SOL limits users ability to move funds. Reddit posts: 1, 2, 3

Screenshot 2024-03-08 at 14 57 08

Related

High fee mitigation with a faux 'sending' phase of the SOL TX. https://github.com/trezor/trezor-suite/pull/11033

sime avatar Mar 08 '24 14:03 sime

As discussed offline I’m writing here the proposal for SOL priority fees implementation. Should you have any questions or ideas for improvements, please let me know. cc @matejcik for the Firmware section below 🙏

Priority fees docs.

Compute unit price of transactions

SOL transfer: 150 (tx example) - 450 (tx example) (Solana docs actually mention 300, perhaps it’s 300 without the compute unit limit instruction)

Token transfer: 5876 (tx example)

Token transfer with account creation: 26663 (tx example)

The values might vary if priority fees are included, I’d check the values properly during implementation.

Trezor Suite

Fee fetching and computation

Recent priority fees can be fetched using the getRecentPrioritizationFees RPC call which returns fee data from the most recent 150 blocks.

We’d like to use TrezorConnect.BlockchainEstimateFee to estimate the fee which would require adding an estimateFee function to the Solana worker. The estimateFee function would call the getRecentPrioritizationFees RPC function, take the 25th percentile value of the fees returned and use that value as the compute unit price.

const computeUnitPriceLamports = _.sortBy(
  recentFees.map((f) => f.prioritizationFee),
).reverse()[Math.floor(recentFees.length / 4)]

There will however be also a minimum priority fee added to each transaction in case the fees fetched from the network are 0 (which is most of the time). This will be equal to 4000 lamports (default fee is 5000 lamports). 100_000 micro-lamports compute unit price * 40_000 compute unit limit.

const DEFAULT_COMPUTE_UNIT_PRICE = 100_000 // used as default by other wallets, micro-lamports
const DEFAULT_COMPUTE_UNIT_LIMIT = 40_000 // should be enough to cover transactions made via Trezor Suite

const computeUnitPriceLamports = DEFAULT_COMPUTE_UNIT_PRICE * (10 ** -6)
const finalFeeLamports = 5000 + (computeUnitPriceLamports * DEFAULT_COMPUTE_UNIT_LIMIT)
// 9000 lamports

40_000 compute unit limit should be enough for transaction made by Suite - I’d verify this though during development as the default seems to be 200K per instruction. The compute unit limit could also be adjusted depending on the transaction but given the fees on Solana are rather low, this seems unnecessary (other wallets default to 200_000 or 300_000 compute units for all their transactions).

The resulting default fee in Suite would thus be 9000 lamports (i.e. almost twice the fee without priority fees). In times of network congestion, the price would increase depending on the values returned from the getRecentPrioritizationFees RPC function.

Transaction building

Hopefully the only other changes would need to be made in solanaUtils (or sendFormSolanaThunks) where the transactions are being built. We would need to modify all transactions to include the ComputeBudget instructions with the priority fees.

Firmware

Trezor Firmware supports a feature we can call “simplified UI” for SOL transfers and Token transfers (with or without token account creation). This feature however doesn’t take Priority Fees’ instructions into consideration and so the “simplified UI” would never be shown for transactions including priority fees i.e. all Suite transactions in the future.

Firmware would thus also need to be updated to ignore SetComputeUnitLimit and SetComputeUnitPrice instructions when determining whether a “simplified UI” should be shown (around here).

Also since these two compute budget instructions (SetComputeUnitLimit and SetComputeUnitPrice) affect only the fee which is properly displayed on Trezor, we can safely always hide these two instructions from the user (i.e. not only in “simplified UI”).

gabrielKerekes avatar Mar 12 '24 13:03 gabrielKerekes

@trezor/qa can we close this? Is it OK? :)

MiroslavProchazka avatar Apr 09 '24 19:04 MiroslavProchazka