Skip to content

Commit

Permalink
chore(connect): build smart levels for eip1559
Browse files Browse the repository at this point in the history
  • Loading branch information
enjojoy committed Jan 16, 2025
1 parent f1bfd82 commit f52e4b0
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 29 deletions.
52 changes: 40 additions & 12 deletions packages/connect/src/api/bitcoin/Fees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,47 @@ export class FeeLevels {
async loadMisc(blockchain: Blockchain) {
try {
const [response] = await blockchain.estimateFee({ blocks: [1] });

if (response.eip1559) {
const eip1559LevelKeys = ['low', 'medium', 'high'] as const;

const { eip1559, ...baseLevel } = response;
const eip1559Levels = eip1559LevelKeys.map(levelKey => {
const level = eip1559[levelKey]; // TypeScript recognizes level as a specific type

return {
label: levelKey, // Use the key (low, medium, high) as the label
feePerUnit: undefined,
maxFeePerGas: level.maxFeePerGas, // Use maxFeePerGas as feePerUnit
maxPriorityFeePerGas: level.maxPriorityFeePerGas,
minWaitTimeEstimate: level.minWaitTimeEstimate,
maxWaitTimeEstimate: level.maxWaitTimeEstimate,
feeLimit: undefined, // Reuse feeLimit from the base level
ethFeeType: 'eip1559' as const,
blocks: -1,
};
});

this.levels = [
{ ...baseLevel, label: 'normal' as const, blocks: -1, ethFeeType: 'legacy' },
...eip1559Levels,
];
} else {
this.levels[0] = {
...this.levels[0],
...response,
// validate `feePerUnit` from the backend
// should be lower than `coinInfo.maxFee` and higher than `coinInfo.minFee`
// xrp sends values from 1 to very high number occasionally
// see: https://github.com/trezor/trezor-suite/blob/develop/packages/blockchain-link/src/workers/ripple/index.ts#L316
feePerUnit: Math.min(
this.coinInfo.maxFee,
Math.max(this.coinInfo.minFee, parseInt(response.feePerUnit, 10)),
).toString(),
};
}

// misc coins should have only one FeeLevel (normal)
this.levels[0] = {
...this.levels[0],
...response,
// validate `feePerUnit` from the backend
// should be lower than `coinInfo.maxFee` and higher than `coinInfo.minFee`
// xrp sends values from 1 to very high number occasionally
// see: https://github.com/trezor/trezor-suite/blob/develop/packages/blockchain-link/src/workers/ripple/index.ts#L316
feePerUnit: Math.min(
this.coinInfo.maxFee,
Math.max(this.coinInfo.minFee, parseInt(response.feePerUnit, 10)),
).toString(),
};
} catch {
// silent
}
Expand Down
17 changes: 8 additions & 9 deletions packages/connect/src/types/fees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,18 @@ export const FeeLevel = Type.Object({
Type.Literal('economy'),
Type.Literal('low'),
Type.Literal('custom'),
Type.Literal('medium'),
]),
feePerUnit: Type.String(),
ethFeeType: Type.Optional(Type.Union([Type.Literal('legacy'), Type.Literal('eip1559')])),
feePerUnit: Type.Optional(Type.String()),
blocks: Type.Number(),
feeLimit: Type.Optional(Type.String()), // eth gas limit
feePerTx: Type.Optional(Type.String()), // fee for BlockchainEstimateFeeParams.request.specific
eip1559: Type.Optional(
Type.Object({
baseFeePerGas: Type.String(),
high: PriorityFeeEstimationDetails,
low: PriorityFeeEstimationDetails,
medium: PriorityFeeEstimationDetails,
}),
),
baseFeePerGas: Type.Optional(Type.String()),
maxFeePerGas: Type.Optional(Type.String()),
maxPriorityFeePerGas: Type.Optional(Type.String()),
maxWaitTimeEstimate: Type.Optional(Type.Number()),
minWaitTimeEstimate: Type.Optional(Type.Number()),
});

export type SelectFeeLevel = Static<typeof SelectFeeLevel>;
Expand Down
8 changes: 3 additions & 5 deletions suite-common/wallet-core/src/blockchain/blockchainThunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const getAccountSyncInterval = (symbol: NetworkSymbol) =>

// sort FeeLevels in reversed order (Low > High)
// TODO: consider to use same order in @trezor/connect to avoid double sorting
const order: FeeLevel['label'][] = ['low', 'economy', 'normal', 'high'];
const order: FeeLevel['label'][] = ['low', 'economy', 'medium', 'normal', 'high'];
const sortLevels = (levels: FeeLevel[]) =>
levels.sort((levelA, levelB) => order.indexOf(levelA.label) - order.indexOf(levelB.label));

Expand Down Expand Up @@ -124,13 +124,11 @@ export const updateFeeInfoThunk = createThunk(
let newFeeInfo;

if (network.networkType === 'ethereum') {
// NOTE: ethereum smart fees are not implemented properly in @trezor/connect Issue: https://github.com/trezor/trezor-suite/issues/5340
// create raw call to @trezor/blockchain-link, receive data and create FeeLevel.normal from it

const result = await TrezorConnect.blockchainEstimateFee({
coin: network.symbol,
request: {
blocks: [2],
feeLevels: 'smart',
specific: {
from: '0x0000000000000000000000000000000000000000',
to: '0x0000000000000000000000000000000000000000',
Expand All @@ -143,7 +141,7 @@ export const updateFeeInfoThunk = createThunk(
levels: result.payload.levels.map(l => ({
...l,
blocks: -1, // NOTE: @trezor/connect returns -1 for ethereum default
label: 'normal' as const,
label: l.label || 'normal',
})),
};
}
Expand Down
2 changes: 1 addition & 1 deletion suite-common/wallet-core/src/fees/feesReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,6 @@ export const selectNetworkFeeLevelFeePerUnit = createMemoizedSelector(
(feeLevel): string | null => {
if (!feeLevel) return null;

return feeLevel.feePerUnit;
return feeLevel.feePerUnit ?? '0';
},
);
4 changes: 2 additions & 2 deletions suite-native/module-send/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const constructFormDraft = ({
selectedUtxos: [],
options: [],
selectedFee: feeLevel.label,
feePerUnit: feeLevel.feePerUnit,
feeLimit: feeLevel.feeLimit ?? '',
feePerUnit: feeLevel.feePerUnit ?? '0',
feeLimit: feeLevel.feeLimit ?? '0',
...restFormValues,
});

0 comments on commit f52e4b0

Please sign in to comment.