Skip to content

Commit

Permalink
feat: support batch estimate fee through tenderly on hw OK-34493 (#6399)
Browse files Browse the repository at this point in the history
* fix: hw/external account no use multiple popover

Signed-off-by: 王山栋 <[email protected]>

* feat: swap send confirm entry

* feat: batch estimate swap fee on hw&external

* fix: lint

---------

Signed-off-by: 王山栋 <[email protected]>
Co-authored-by: 王山栋 <[email protected]>
  • Loading branch information
weatherstar and ezailWang authored Dec 23, 2024
1 parent 7c70803 commit 736d593
Show file tree
Hide file tree
Showing 11 changed files with 243 additions and 13 deletions.
3 changes: 2 additions & 1 deletion packages/core/src/types/coreTypesTx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type {
IApproveInfo,
ITransferInfo,
} from '@onekeyhq/kit-bg/src/vaults/types';
import type { IFeeInfoUnit } from '@onekeyhq/shared/types/fee';
import type { IFeeInfoUnit, IFeesInfoUnit } from '@onekeyhq/shared/types/fee';
import type { IEncodedTxLightning } from '@onekeyhq/shared/types/lightning';
import type { IStakingInfo } from '@onekeyhq/shared/types/staking';
import type { ISwapTxInfo } from '@onekeyhq/shared/types/swap/types';
Expand Down Expand Up @@ -107,6 +107,7 @@ export type IUnsignedTx = {
export type IUnsignedTxPro = IUnsignedTx & {
encodedTx: IEncodedTx;
feeInfo?: IFeeInfoUnit | undefined;
feesInfo?: IFeesInfoUnit | undefined;
swapInfo?: ISwapTxInfo | undefined;
approveInfo?: IApproveInfo | undefined;
stakingInfo?: IStakingInfo;
Expand Down
8 changes: 6 additions & 2 deletions packages/kit/src/hooks/useSendConfirm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,12 @@ function useSendConfirm(params: IParams) {
);
}

const target = params.isInternalSwap
? EModalSendRoutes.SendConfirmFromSwap
: EModalSendRoutes.SendConfirm;

if (sameModal) {
navigation.push(EModalSendRoutes.SendConfirm, {
navigation.push(target, {
accountId,
networkId,
unsignedTxs,
Expand All @@ -131,7 +135,7 @@ function useSendConfirm(params: IParams) {
});
} else {
navigation.pushModal(EModalRoutes.SendModal, {
screen: EModalSendRoutes.SendConfirm,
screen: target,
params: {
accountId,
networkId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ const ToastGallery = () => (
onPress={() => {
Toast.success({
title: 'url!',
message: 'look, <url href="https://onekey.so">OneKey</url> here. aaa',
message:
'look, <url href="https://onekey.so">OneKey</url> here. aaa',
});
}}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type IProps = {
transferPayload: ITransferPayload | undefined;
useFeeInTx?: boolean;
feeInfoEditable?: boolean;
popStack?: boolean;
};

function SendConfirmActionsContainer(props: IProps) {
Expand All @@ -66,6 +67,7 @@ function SendConfirmActionsContainer(props: IProps) {
transferPayload,
useFeeInTx,
feeInfoEditable,
popStack = true,
} = props;
const intl = useIntl();
const isSubmitted = useRef(false);
Expand Down Expand Up @@ -243,7 +245,11 @@ function SendConfirmActionsContainer(props: IProps) {

void dappApprove.resolve({ result: signedTx });

navigation.popStack();
if (popStack) {
navigation.popStack();
} else {
navigation.pop();
}
updateSendTxStatus({ isSubmitting: false });
onSuccess?.(result);
} catch (e: any) {
Expand Down Expand Up @@ -276,8 +282,9 @@ function SendConfirmActionsContainer(props: IProps) {
sourceInfo,
transferPayload,
intl,
navigation,
popStack,
onSuccess,
navigation,
]);

const cancelCalledRef = useRef(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ function SendConfirmContainer() {
useFeeInTx,
transferPayload,
feeInfoEditable,
popStack,
} = route.params;

const dappApprove = useDappApproveAction({
Expand Down Expand Up @@ -208,6 +209,7 @@ function SendConfirmContainer() {
/>
</Page.Body>
<SendConfirmActionsContainer
popStack={popStack}
sourceInfo={sourceInfo}
signOnly={signOnly}
accountId={accountId}
Expand All @@ -233,6 +235,7 @@ function SendConfirmContainer() {
networkId,
transferPayload,
unsignedTxs,
popStack,
signOnly,
onSuccess,
onFail,
Expand Down
21 changes: 21 additions & 0 deletions packages/kit/src/views/Send/pages/SendConfirm/TxFeeContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ function TxFeeContainer(props: IProps) {
[unsignedTxs],
);

const isSingleTxWithFeesInfo = useMemo(
() => unsignedTxs.length === 1 && unsignedTxs[0].feesInfo,
[unsignedTxs],
);

const isSecondApproveTxWithFeeInfo = useMemo(
() =>
unsignedTxs.length === 1 &&
Expand Down Expand Up @@ -185,6 +190,21 @@ function TxFeeContainer(props: IProps) {
encodedTx: unsignedTxs[0].encodedTx,
});

if (isSingleTxWithFeesInfo) {
const r = unsignedTxs[0].feesInfo;
updateSendFeeStatus({
status: ESendFeeStatus.Success,
errMessage: '',
});
setTxFeeInit(true);
updateTxAdvancedSettings({ dataChanged: false });
return {
r,
e,
m: undefined,
};
}

if (
(isLastSwapTxWithFeeInfo || isSecondApproveTxWithFeeInfo) &&
unsignedTxs[0].feeInfo
Expand Down Expand Up @@ -256,6 +276,7 @@ function TxFeeContainer(props: IProps) {
isLastSwapTxWithFeeInfo,
isMultiTxs,
isSecondApproveTxWithFeeInfo,
isSingleTxWithFeesInfo,
networkId,
unsignedTxs,
updateSendFeeStatus,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import { useCallback, useEffect, useRef } from 'react';

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

import { Page, Spinner, Stack } from '@onekeyhq/components';
import backgroundApiProxy from '@onekeyhq/kit/src/background/instance/backgroundApiProxy';
import useAppNavigation from '@onekeyhq/kit/src/hooks/useAppNavigation';
import type { IModalSendParamList } from '@onekeyhq/shared/src/routes';
import { EModalSendRoutes } from '@onekeyhq/shared/src/routes';
import accountUtils from '@onekeyhq/shared/src/utils/accountUtils';
import type { IGasEIP1559, IGasLegacy } from '@onekeyhq/shared/types/fee';
import type { ISendTxOnSuccessData } from '@onekeyhq/shared/types/tx';

import type { RouteProp } from '@react-navigation/core';
import type { StackActionType } from '@react-navigation/native';

function SendConfirmFromSwap() {
const pendingAction = useRef<StackActionType>();
const navigation = useNavigation();
const appNavigation = useAppNavigation();

const route =
useRoute<
RouteProp<IModalSendParamList, EModalSendRoutes.SendConfirmFromSwap>
>();

const { networkId, accountId, unsignedTxs, onSuccess, onFail, onCancel } =
route.params;

const handleConfirmMultiTxsOnHwOrExternal = useCallback(
async (multiTxsFeeResult: {
common: {
baseFee: string | undefined;
feeDecimals: number;
feeSymbol: string;
nativeDecimals: number;
nativeSymbol: string;
nativeTokenPrice: number | undefined;
};
txFees: {
gas: IGasLegacy[];
gasEIP1559: IGasEIP1559[];
}[];
}) => {
for (let i = 0, len = unsignedTxs.length; i < len; i += 1) {
const unsignedTx = unsignedTxs[i];
unsignedTx.feesInfo = {
common: multiTxsFeeResult.common,
gas: multiTxsFeeResult.txFees[i].gas,
gasEIP1559: multiTxsFeeResult.txFees[i].gasEIP1559,
};
const isLastTx = i === len - 1;

await new Promise((resolve) => {
appNavigation.push(EModalSendRoutes.SendConfirm, {
...route.params,
popStack: false,
unsignedTxs: [unsignedTx],
onSuccess: (data: ISendTxOnSuccessData[]) => {
if (isLastTx) {
onSuccess?.(data);
appNavigation.popStack();
}
resolve(data);
},
onFail: (error: Error) => {
onFail?.(error);

appNavigation.popStack();
},
onCancel: () => {
onCancel?.();
appNavigation.popStack();
},
});
});
}
},
[unsignedTxs, appNavigation, route.params, onSuccess, onFail, onCancel],
);

const navigationToSendConfirm = useCallback(async () => {
let action: any;
let batchEstimateButSingleConfirm = false;
const isMultiTxs = unsignedTxs.length > 1;
if (
isMultiTxs &&
(accountUtils.isHwAccount({ accountId }) ||
accountUtils.isExternalAccount({ accountId }))
) {
const vaultSettings =
await backgroundApiProxy.serviceNetwork.getVaultSettings({
networkId,
});
if (vaultSettings.supportBatchEstimateFee?.[networkId]) {
try {
const encodedTxList = unsignedTxs.map((tx) => tx.encodedTx);
const multiTxsFeeResult =
await backgroundApiProxy.serviceGas.batchEstimateFee({
accountId,
networkId,
encodedTxs: encodedTxList,
});
if (multiTxsFeeResult.txFees.length === unsignedTxs.length) {
await handleConfirmMultiTxsOnHwOrExternal(multiTxsFeeResult);
batchEstimateButSingleConfirm = true;
} else {
batchEstimateButSingleConfirm = false;
}
} catch (e) {
batchEstimateButSingleConfirm = false;
}
}
}

if (!batchEstimateButSingleConfirm) {
action = StackActions.replace(EModalSendRoutes.SendConfirm, {
...route.params,
// @ts-ignore
_disabledAnimationOfNavigate: true,
});
}

if (action) {
if (AppState.currentState === 'active') {
setTimeout(() => navigation.dispatch(action));
} else {
pendingAction.current = action;
}
}
}, [
accountId,
handleConfirmMultiTxsOnHwOrExternal,
navigation,
networkId,
route.params,
unsignedTxs,
]);

const handleOnClose = () => {
onCancel?.();
};

useEffect(() => {
void navigationToSendConfirm();
}, [navigation, navigationToSendConfirm, route.params, unsignedTxs]);

return (
<Page onClose={handleOnClose}>
<Page.Body>
<Stack h="100%" justifyContent="center" alignContent="center">
<Spinner size="large" />
</Stack>
</Page.Body>
</Page>
);
}
export { SendConfirmFromSwap };
5 changes: 5 additions & 0 deletions packages/kit/src/views/Send/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { EModalSendRoutes } from '@onekeyhq/shared/src/routes';

import { LazyLoadPage } from '../../../components/LazyLoadPage';
import { SendConfirmFromDApp } from '../pages/SendConfirmFromDApp/SendConfirmFromDApp';
import { SendConfirmFromSwap } from '../pages/SendConfirmFromSwap/SendConfirmFromSwap';

const LnurlPayRequestModal = LazyLoadPage(
() =>
Expand Down Expand Up @@ -63,6 +64,10 @@ export const ModalSendStack: IModalFlowNavigatorConfig<
name: EModalSendRoutes.SendConfirmFromDApp,
component: SendConfirmFromDApp,
},
{
name: EModalSendRoutes.SendConfirmFromSwap,
component: SendConfirmFromSwap,
},
{
name: EModalSendRoutes.SendReplaceTx,
component: SendReplaceTx,
Expand Down
7 changes: 0 additions & 7 deletions packages/kit/src/views/Swap/hooks/useSwapBuiltTx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import type {
} from '@onekeyhq/kit-bg/src/vaults/types';
import { ETranslations } from '@onekeyhq/shared/src/locale';
import { defaultLogger } from '@onekeyhq/shared/src/logger/logger';
import accountUtils from '@onekeyhq/shared/src/utils/accountUtils';
import {
numberFormat,
toBigIntHex,
Expand Down Expand Up @@ -571,12 +570,6 @@ export function useSwapBuildTx() {
const createBuildTxRes = await createBuildTx();
if (createBuildTxRes) {
if (
accountUtils.isHwAccount({
accountId: swapFromAddressInfo.accountInfo.account.id,
}) ||
accountUtils.isExternalAccount({
accountId: swapFromAddressInfo.accountInfo.account.id,
}) ||
SwapBuildUseMultiplePopoversNetworkIds.includes(
fromToken.networkId,
)
Expand Down
15 changes: 15 additions & 0 deletions packages/shared/src/routes/send.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import type { EReplaceTxType, ISendTxOnSuccessData } from '../../types/tx';
export enum EModalSendRoutes {
SendDataInput = 'SendDataInput',
SendConfirmFromDApp = 'SendConfirmFromDApp',
SendConfirmFromSwap = 'SendConfirmFromSwap',
SendConfirm = 'SendConfirm',
SendFeedback = 'SendFeedback',
SendReplaceTx = 'SendReplaceTx',
Expand Down Expand Up @@ -63,8 +64,22 @@ export type IModalSendParamList = {
onFail?: (error: Error) => void;
onCancel?: () => void;
transferPayload?: ITransferPayload;
popStack?: boolean;
};
[EModalSendRoutes.SendConfirmFromDApp]: undefined;
[EModalSendRoutes.SendConfirmFromSwap]: {
networkId: string;
accountId: string;
unsignedTxs: IUnsignedTxPro[];
sourceInfo?: IDappSourceInfo;
signOnly?: boolean;
useFeeInTx?: boolean;
feeInfoEditable?: boolean;
onSuccess?: (txs: ISendTxOnSuccessData[]) => void;
onFail?: (error: Error) => void;
onCancel?: () => void;
transferPayload?: ITransferPayload;
};
[EModalSendRoutes.SendReplaceTx]: {
networkId: string;
accountId: string;
Expand Down
Loading

0 comments on commit 736d593

Please sign in to comment.