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

v4 fix: several fee issues OK-26141 OK-25859 OK-26144 #4243

Merged
merged 4 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 0 additions & 33 deletions packages/engine/src/vaults/impl/evm/Vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1294,31 +1294,6 @@ export default class Vault extends VaultBase {
prices?.length && prices?.every((price) => typeof price === 'object'),
);

const gasLimitInTx = new BigNumber(
encodedTx.gas ?? encodedTx.gasLimit ?? 0,
).toFixed();
// NOTE: gasPrice deleted in removeFeeInfoInTx() if encodedTx build by DAPP
let gasPriceInTx: string | EIP1559Fee | undefined = encodedTx.gasPrice
? this._toNormalAmount(encodedTx.gasPrice, network.feeDecimals)
: undefined;
if (eip1559) {
gasPriceInTx = merge(
{
...(prices[0] as EIP1559Fee),
},
{
maxPriorityFeePerGas: encodedTx.maxPriorityFeePerGas
? this._toNormalAmount(
encodedTx.maxPriorityFeePerGas,
network.feeDecimals,
)
: undefined,
maxFeePerGas: encodedTx.maxFeePerGas
? this._toNormalAmount(encodedTx.maxFeePerGas, network.feeDecimals)
: undefined,
},
) as EIP1559Fee;
}
// [{baseFee: '928.361757873', maxPriorityFeePerGas: '11.36366', maxFeePerGas: '939.725417873'}]
// [10]
const limit = BigNumber.max(
Expand All @@ -1343,14 +1318,6 @@ export default class Vault extends VaultBase {
prices,
defaultPresetIndex: '1',

// feeInfo in original tx
tx: {
eip1559,
limit: gasLimitInTx,
...(eip1559
? { price1559: gasPriceInTx as EIP1559Fee }
: { price: gasPriceInTx as string }),
},
baseFeeValue,
extraInfo: {
networkCongestion,
Expand Down
78 changes: 71 additions & 7 deletions packages/engine/src/vaults/impl/sol/Vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@ import {
getAssociatedTokenAddressSync,
} from '@solana/spl-token';
import {
ComputeBudgetInstruction,
ComputeBudgetProgram,
MessageAccountKeys,
PublicKey,
SYSVAR_INSTRUCTIONS_PUBKEY,
SystemInstruction,
SystemProgram,
Transaction,
TransactionMessage,
VersionedTransaction,
} from '@solana/web3.js';
import axios from 'axios';
Expand Down Expand Up @@ -1037,14 +1040,73 @@ export default class Vault extends VaultBase {
return Promise.resolve(encodedTx);
}

const nativeTx = (await this.helper.parseToNativeTx(
encodedTx,
)) as Transaction;
const [instruction] = nativeTx.instructions;
const nativeTx = await this.helper.parseToNativeTx(encodedTx);

// add priority fees to DApp tx by default
try {
if (options.type === IEncodedTxUpdateType.priorityFees) {
const isVersionedTransaction = nativeTx instanceof VersionedTransaction;
let instructions: TransactionInstruction[] = [];
let unitPrice;
let transactionMessage;
if (isVersionedTransaction) {
transactionMessage = TransactionMessage.decompile(nativeTx.message);
instructions = transactionMessage.instructions;
} else {
instructions = nativeTx.instructions;
}

// try to find if the transaction has already set the compute unit price(priority fee)
try {
for (const instruction of instructions) {
unitPrice =
ComputeBudgetInstruction.decodeSetComputeUnitPrice(instruction);
}
} catch {
// pass
}

// if not set, add the compute unit price(priority fee) to the transaction
if (isNil(unitPrice)) {
const client = await this.getClient();
const accountAddress = await this.getAccountAddress();
const prioritizationFee = await client.getRecentMaxPrioritizationFees(
[accountAddress],
);

const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({
microLamports: Math.max(MIN_PRIORITY_FEE, prioritizationFee),
});

if (isVersionedTransaction) {
transactionMessage?.instructions.push(addPriorityFee);
} else {
(nativeTx as Transaction).add(addPriorityFee);
}
}

if (isVersionedTransaction) {
return bs58.encode(
new VersionedTransaction(
(transactionMessage as TransactionMessage).compileToV0Message(),
).serialize(),
);
}

return bs58.encode(
(nativeTx as Transaction).serialize({ requireAllSignatures: false }),
);
}
} catch (e) {
return encodedTx;
}

const nativeTxForUpdateTransfer = nativeTx as Transaction;
const [instruction] = nativeTxForUpdateTransfer.instructions;
// max native token transfer update
if (
options.type === 'transfer' &&
nativeTx.instructions.length === 1 &&
nativeTxForUpdateTransfer.instructions.length === 1 &&
instruction.programId.toString() === SystemProgram.programId.toString()
) {
const instructionType =
Expand All @@ -1056,7 +1118,7 @@ export default class Vault extends VaultBase {
this.networkId,
);
const { amount } = payload as IEncodedTxUpdatePayloadTransfer;
nativeTx.instructions = [
nativeTxForUpdateTransfer.instructions = [
SystemProgram.transfer({
fromPubkey,
toPubkey,
Expand All @@ -1065,7 +1127,9 @@ export default class Vault extends VaultBase {
),
}),
];
return bs58.encode(nativeTx.serialize({ requireAllSignatures: false }));
return bs58.encode(
nativeTxForUpdateTransfer.serialize({ requireAllSignatures: false }),
);
}
}
return Promise.resolve(encodedTx);
Expand Down
1 change: 1 addition & 0 deletions packages/engine/src/vaults/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ export enum IEncodedTxUpdateType {
cancel = 'cancel',
advancedSettings = 'advancedSettings',
customData = 'customData',
priorityFees = 'priorityFees',
}

export type IEncodedTxUpdateOptions = {
Expand Down
72 changes: 52 additions & 20 deletions packages/kit/src/views/Send/modals/SendConfirmFromDapp.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { useEffect, useRef } from 'react';
import { useCallback, useEffect, useRef } from 'react';

import { StackActions, useNavigation } from '@react-navigation/native';
import { AppState } from 'react-native';

import type { IEncodedTxBtc } from '@onekeyhq/engine/src/vaults/impl/btc/types';
import { IEncodedTxUpdateType } from '@onekeyhq/engine/src/vaults/types';
import { IMPL_SOL } from '@onekeyhq/shared/src/engine/engineConsts';

import backgroundApiProxy from '../../../background/instance/backgroundApiProxy';
import { getActiveWalletAccount } from '../../../hooks';
import useDappParams from '../../../hooks/useDappParams';
import { useReduxReady } from '../../../hooks/useReduxReady';
Expand Down Expand Up @@ -35,37 +38,37 @@ export function SendConfirmFromDapp() {
_$t = undefined,
networkId: dappNetworkId,
} = useDappParams();
useEffect(() => {
if (!isReady) {
return;
}
// OK-16560: navigate when app in background would cause modal render in wrong size
const appStateListener = AppState.addEventListener('change', (state) => {
if (state === 'active') {
setTimeout(() => {
if (pendingAction.current) {
navigation.dispatch(pendingAction.current);
pendingAction.current = undefined;
}
});
}
});

const navigateToSendConfirm = useCallback(async () => {
let action: any;
// TODO get network and account from dapp connections
const { networkId, accountId } = getActiveWalletAccount();
const { networkId, accountId, networkImpl } = getActiveWalletAccount();

// alert(JSON.stringify({ networkId, accountId, isReady }));
// TODO providerName
if (encodedTx) {
const isPsbt = (encodedTx as IEncodedTxBtc).psbtHex;
let newEncodedTx = encodedTx;
const isPsbt = (newEncodedTx as IEncodedTxBtc).psbtHex;

if (networkImpl === IMPL_SOL) {
newEncodedTx = await backgroundApiProxy.engine.updateEncodedTx({
accountId,
networkId,
encodedTx,
payload: {},
options: {
type: IEncodedTxUpdateType.priorityFees,
},
});
}

const params: SendConfirmParams = {
networkId: dappNetworkId ?? networkId,
accountId,
sourceInfo,
encodedTx,
encodedTx: newEncodedTx,
feeInfoEditable: !isPsbt,
feeInfoUseFeeInTx: !!isPsbt,
feeInfoUseFeeInTx: true,
ignoreFetchFeeCalling: !!isPsbt,
signOnly,
// @ts-ignore
Expand Down Expand Up @@ -95,6 +98,34 @@ export function SendConfirmFromDapp() {
pendingAction.current = action;
}
}
}, [
_$t,
dappNetworkId,
encodedTx,
navigation,
signOnly,
sourceInfo,
unsignedMessage,
]);

useEffect(() => {
if (!isReady) {
return;
}
// OK-16560: navigate when app in background would cause modal render in wrong size
const appStateListener = AppState.addEventListener('change', (state) => {
if (state === 'active') {
setTimeout(() => {
if (pendingAction.current) {
navigation.dispatch(pendingAction.current);
pendingAction.current = undefined;
}
});
}
});

navigateToSendConfirm();

return () => {
appStateListener.remove();
};
Expand All @@ -107,6 +138,7 @@ export function SendConfirmFromDapp() {
unsignedMessage,
signOnly,
dappNetworkId,
navigateToSendConfirm,
]);

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,11 @@ export async function prepareSendConfirmEncodedTx({
// routeParams is not editable, so should create new one
let tx = { ...encodedTxEvm };
tx.from = tx.from || address;
// remove gas price if encodedTx build by DAPP
if (sendConfirmParams.sourceInfo) {
tx = removeFeeInfoInTx(tx);
}
// keep gas price if encodedTx build by DAPP

// if (sendConfirmParams.sourceInfo) {
// tx = removeFeeInfoInTx(tx);
// }

// Ensure IEncodedTxEvm's value is hex string.
if (tx.value && tx.value.startsWith && !tx.value.startsWith('0x')) {
Expand Down
24 changes: 20 additions & 4 deletions packages/kit/src/views/Send/utils/useFeeInfoPayload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import BigNumber from 'bignumber.js';

import { ToastManager } from '@onekeyhq/components';
import { FailedToEstimatedGasError } from '@onekeyhq/engine/src/errors';
import type { EIP1559Fee } from '@onekeyhq/engine/src/types/network';
import type { IEncodedTxEvm } from '@onekeyhq/engine/src/vaults/impl/evm/Vault';
import type {
IEncodedTx,
Expand Down Expand Up @@ -163,7 +164,6 @@ export function useFeeInfoPayload({
gasPrice,
} = encodedTx as IEncodedTxEvm;
const limit = gasLimit || gas;

if (maxFeePerGas && maxPriorityFeePerGas) {
const price1559 = {
baseFee: new BigNumber(gasPrice ?? 0)
Expand All @@ -177,23 +177,39 @@ export function useFeeInfoPayload({
.toFixed(),
};
info.eip1559 = true;
info.limit = limit;
info.limit = limit || info.limit;
info.prices = [price1559];
info.tx = {
eip1559: true,
limit,
price1559,
};
} else {
} else if (gasPrice) {
const price = new BigNumber(gasPrice ?? 0)
.shiftedBy(-(feeDecimals ?? 0))
.toFixed();
info.limit = limit;
info.limit = limit || info.limit;
info.prices = [price];
info.tx = {
limit,
price,
};
} else if (limit) {
info.tx = {
limit,
eip1559: info.eip1559,
...(info.eip1559
? {
price1559: info.prices[
Number(info.defaultPresetIndex)
] as EIP1559Fee,
}
: {
price: info.prices[
Number(info.defaultPresetIndex)
] as string,
}),
};
}
}
}
Expand Down
Loading