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

[Issue-3658] Allow customizing fee for substrate/evm transactions #3989

Open
wants to merge 27 commits into
base: subwallet-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
70dacfe
[Update] - Update message in case perform Liquid staking have XCM
tunghp2002 Oct 23, 2024
695376b
Merge branch 'subwallet-dev' into koni/dev/issue-3745
tunghp2002 Nov 22, 2024
d5550e3
[Add] Extension - Handle negative number
tunghp2002 Nov 27, 2024
6bd8c6d
Merge branch 'subwallet-dev' into koni/dev/issue-3745
tunghp2002 Dec 19, 2024
d0fa8c0
[Update] Fix acala liquid staking screen
tunghp2002 Dec 19, 2024
142010c
[Update] Add number for alt token
tunghp2002 Dec 25, 2024
22e1de5
[Update] Refactor code by use util
tunghp2002 Dec 25, 2024
dc320da
For test
tunghp2002 Dec 30, 2024
c7ca8e5
[Update] Fix logic earning and xcm
tunghp2002 Dec 31, 2024
320d586
[Fixed] Fixed missing amount display
tunghp2002 Dec 31, 2024
dc29965
[Update] Change content
tunghp2002 Dec 31, 2024
4629d9b
[Fix] Sum
tunghp2002 Jan 2, 2025
b660a02
[Hot fix] Format popup message
tunghp2002 Jan 2, 2025
c705900
Merge branch 'subwallet-dev' into koni/dev/issue-3745
tunghp2002 Jan 10, 2025
a1232c6
Merge branch 'subwallet-dev' into koni/dev/issue-3745
tunghp2002 Jan 10, 2025
153b100
Merge pull request #3800 from Koniverse/koni/dev/issue-3745
saltict Jan 10, 2025
3758f46
[Issue-3658] feat: Add Interface to support custom fee transactions
dungnguyen-art Jan 10, 2025
a5c3591
[Issue-3658] feat: Add utility function and logic to subscribe for ge…
dungnguyen-art Jan 10, 2025
582568f
[Issue-3658] feat: Add UI for custom fee transaction
dungnguyen-art Jan 10, 2025
5f31ee5
[Issue-3658] feat: Add logic to get maximum transferable amount
dungnguyen-art Jan 13, 2025
ae514bc
[Issue-3658] feat: Add logic UI to display "fee options"
dungnguyen-art Jan 13, 2025
3621e27
[Issue-3658] docs: Add TODO comments for subscribe max transferable l…
dungnguyen-art Jan 13, 2025
fb04a8b
[Issue-3658] Update UI and handle validate transaction
dungnguyen-art Jan 15, 2025
fccd2b1
[Issue-3658] Update custom fee for XCM, Bridge, dapps
dungnguyen-art Jan 16, 2025
fe58b5a
[Issue-3658] Update ui
dungnguyen-art Jan 17, 2025
7877d98
[Issue-3658] Update validate and handle decimal
dungnguyen-art Jan 21, 2025
f182033
[Issue-3658] refactor code
dungnguyen-art Jan 21, 2025
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
4 changes: 3 additions & 1 deletion packages/extension-base/src/background/KoniTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import { SWTransactionResponse, SWTransactionResult } from '@subwallet/extension-base/services/transaction-service/types';
import { WalletConnectNotSupportRequest, WalletConnectSessionRequest } from '@subwallet/extension-base/services/wallet-connect-service/types';
import { AccountJson, AccountsWithCurrentAddress, AddressJson, BalanceJson, BaseRequestSign, BuyServiceInfo, BuyTokenInfo, CommonOptimalPath, CurrentAccountInfo, EarningRewardHistoryItem, EarningRewardJson, EarningStatus, HandleYieldStepParams, InternalRequestSign, LeavePoolAdditionalData, NominationPoolInfo, OptimalYieldPath, OptimalYieldPathParams, RequestAccountBatchExportV2, RequestAccountCreateSuriV2, RequestAccountNameValidate, RequestAccountProxyEdit, RequestAccountProxyForget, RequestBatchJsonGetAccountInfo, RequestBatchRestoreV2, RequestBounceableValidate, RequestChangeTonWalletContractVersion, RequestCheckCrossChainTransfer, RequestCheckPublicAndSecretKey, RequestCheckTransfer, RequestCrossChainTransfer, RequestDeriveCreateMultiple, RequestDeriveCreateV3, RequestDeriveValidateV2, RequestEarlyValidateYield, RequestExportAccountProxyMnemonic, RequestGetAllTonWalletContractVersion, RequestGetDeriveAccounts, RequestGetDeriveSuggestion, RequestGetYieldPoolTargets, RequestInputAccountSubscribe, RequestJsonGetAccountInfo, RequestJsonRestoreV2, RequestMetadataHash, RequestMnemonicCreateV2, RequestMnemonicValidateV2, RequestPrivateKeyValidateV2, RequestShortenMetadata, RequestStakeCancelWithdrawal, RequestStakeClaimReward, RequestTransfer, RequestUnlockDotCheckCanMint, RequestUnlockDotSubscribeMintedData, RequestYieldLeave, RequestYieldStepSubmit, RequestYieldWithdrawal, ResponseAccountBatchExportV2, ResponseAccountCreateSuriV2, ResponseAccountNameValidate, ResponseBatchJsonGetAccountInfo, ResponseCheckPublicAndSecretKey, ResponseDeriveValidateV2, ResponseEarlyValidateYield, ResponseExportAccountProxyMnemonic, ResponseGetAllTonWalletContractVersion, ResponseGetDeriveAccounts, ResponseGetDeriveSuggestion, ResponseGetYieldPoolTargets, ResponseInputAccountSubscribe, ResponseJsonGetAccountInfo, ResponseMetadataHash, ResponseMnemonicCreateV2, ResponseMnemonicValidateV2, ResponsePrivateKeyValidateV2, ResponseShortenMetadata, StorageDataInterface, SubmitYieldStepData, SwapPair, SwapQuoteResponse, SwapRequest, SwapRequestResult, SwapSubmitParams, SwapTxData, TokenSpendingApprovalParams, UnlockDotTransactionNft, UnstakingStatus, ValidateSwapProcessParams, ValidateYieldProcessParams, YieldPoolInfo, YieldPositionInfo } from '@subwallet/extension-base/types';
import { RequestSubmitTransfer, RequestSubscribeTransfer, ResponseSubscribeTransfer } from '@subwallet/extension-base/types/balance/transfer';
import { RequestClaimBridge } from '@subwallet/extension-base/types/bridge';
import { GetNotificationParams, RequestIsClaimedPolygonBridge, RequestSwitchStatusParams } from '@subwallet/extension-base/types/notification';
import { InjectedAccount, InjectedAccountWithMeta, MetadataDefBase } from '@subwallet/extension-inject/types';
Expand Down Expand Up @@ -232,13 +233,13 @@
externalUrl?: string;
rarity?: string;
description?: string;
properties?: Record<any, any> | null;

Check warning on line 236 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type

Check warning on line 236 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type
}

interface NftItemExtraInfo {
type?: _AssetType.ERC721 | _AssetType.PSP34 | RMRK_VER; // for sending
rmrk_ver?: RMRK_VER;
onChainOption?: any; // for sending PSP-34 tokens, should be done better

Check warning on line 242 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type
assetHubType?: AssetHubNftType // for sending assetHub nft. There're 2 types nft
}

Expand Down Expand Up @@ -554,7 +555,7 @@
[ExtrinsicType.STAKING_COMPOUNDING]: RequestTuringStakeCompound,
[ExtrinsicType.STAKING_CANCEL_COMPOUNDING]: RequestTuringCancelStakeCompound,
[ExtrinsicType.STAKING_CANCEL_UNSTAKE]: RequestStakeCancelWithdrawal,
[ExtrinsicType.STAKING_POOL_WITHDRAW]: any,

Check warning on line 558 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type

// Yield
[ExtrinsicType.JOIN_YIELD_POOL]: RequestYieldStepSubmit,
Expand Down Expand Up @@ -585,9 +586,9 @@
[ExtrinsicType.CLAIM_BRIDGE]: RequestClaimBridge

[ExtrinsicType.EVM_EXECUTE]: TransactionConfig,
[ExtrinsicType.CROWDLOAN]: any,

Check warning on line 589 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type
[ExtrinsicType.SWAP]: SwapTxData
[ExtrinsicType.UNKNOWN]: any

Check warning on line 591 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type
}

export enum ExtrinsicStatus {
Expand Down Expand Up @@ -686,7 +687,7 @@
// : T extends ExtrinsicType.MINT_VDOT
// ? Pick<SubmitBifrostLiquidStaking, 'rewardTokenSlug' | 'estimatedAmountReceived'>
// : undefined;
export interface TransactionHistoryItem<ET extends ExtrinsicType = ExtrinsicType.TRANSFER_BALANCE> {

Check warning on line 690 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

'ET' is defined but never used
origin?: 'app' | 'migration' | 'subsquid' | 'subscan', // 'app' or history source
callhash?: string,
signature?: string,
Expand All @@ -711,7 +712,7 @@
tip?: AmountData,
fee?: AmountData,
explorerUrl?: string,
additionalInfo?: any,

Check warning on line 715 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type
startBlock?: number,
nonce?: number,
addressPrefix?: number
Expand Down Expand Up @@ -943,12 +944,12 @@
recipientAddress: string,

nftItemName?: string, // Use for confirmation view only
params: Record<string, any>,

Check warning on line 947 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type
nftItem: NftItem
}

export interface EvmNftTransaction extends ValidateTransactionResponse {
tx: Record<string, any> | null;

Check warning on line 952 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type
}

export interface ValidateNetworkResponse {
Expand Down Expand Up @@ -2151,13 +2152,14 @@
'pri(transaction.history.getSubscription)': [null, TransactionHistoryItem[], TransactionHistoryItem[]];
'pri(transaction.history.subscribe)': [RequestSubscribeHistory, ResponseSubscribeHistory, TransactionHistoryItem[]];
'pri(transfer.getMaxTransferable)': [RequestMaxTransferable, AmountData];
'pri(transfer.subscribe)': [RequestSubscribeTransfer, ResponseSubscribeTransfer, ResponseSubscribeTransfer];
'pri(subscription.cancel)': [string, boolean];
'pri(freeBalance.get)': [RequestFreeBalance, AmountData];
'pri(freeBalance.subscribe)': [RequestFreeBalance, AmountDataWithId, AmountDataWithId];

// Transfer
'pri(accounts.checkTransfer)': [RequestCheckTransfer, ValidateTransactionResponse];
'pri(accounts.transfer)': [RequestTransfer, SWTransactionResponse];
'pri(accounts.transfer)': [RequestSubmitTransfer, SWTransactionResponse];
'pri(accounts.getOptimalTransferProcess)': [RequestOptimalTransferProcess, CommonOptimalPath];
'pri(accounts.approveSpending)': [TokenSpendingApprovalParams, SWTransactionResponse];

Expand Down
33 changes: 19 additions & 14 deletions packages/extension-base/src/core/logic-validation/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import { EvmProviderError } from '@subwallet/extension-base/background/errors/Ev
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
import { ConfirmationType, ErrorValidation, EvmProviderErrorType, EvmSendTransactionParams, EvmSignatureRequest, EvmTransactionData } from '@subwallet/extension-base/background/KoniTypes';
import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
import { calculateGasFeeParams } from '@subwallet/extension-base/services/fee-service/utils';
import { AuthUrlInfo } from '@subwallet/extension-base/services/request-service/types';
import { BasicTxErrorType } from '@subwallet/extension-base/types';
import { BN_ZERO, createPromiseHandler, isSameAddress, stripUrl, wait } from '@subwallet/extension-base/utils';
import { BasicTxErrorType, EvmFeeInfo } from '@subwallet/extension-base/types';
import { BN_ZERO, combineEthFee, createPromiseHandler, isSameAddress, stripUrl, wait } from '@subwallet/extension-base/utils';
import { isContractAddress, parseContractInput } from '@subwallet/extension-base/utils/eth/parseTransaction';
import { getId } from '@subwallet/extension-base/utils/getId';
import { isSubstrateAddress } from '@subwallet/keyring';
import { KeyringPair } from '@subwallet/keyring/types';
import { keyring } from '@subwallet/ui-keyring';
Expand Down Expand Up @@ -434,18 +434,23 @@ export async function validationEvmDataTransactionMiddleware (koni: KoniState, u
estimateGas = new BigN(transactionParams.gasPrice).multipliedBy(transaction.gas).toFixed(0);
} else {
try {
const priority = await calculateGasFeeParams(evmApi, networkKey || '');

if (priority.baseGasFee) {
transaction.maxPriorityFeePerGas = priority.maxPriorityFeePerGas.toString();
transaction.maxFeePerGas = priority.maxFeePerGas.toString();

const maxFee = priority.maxFeePerGas;

estimateGas = maxFee.multipliedBy(transaction.gas).toFixed(0);
const gasLimit = transaction.gas || await evmApi.api.eth.estimateGas(transaction);
const id = getId();
const feeInfo = await koni.feeService.subscribeChainFee(id, transaction.chain || '', 'evm') as EvmFeeInfo;
const feeCombine = combineEthFee(feeInfo);

if (transaction.maxFeePerGas) {
estimateGas = new BigN(transaction.maxFeePerGas.toString()).multipliedBy(gasLimit).toFixed(0);
} else if (transaction.gasPrice) {
estimateGas = new BigN(transaction.gasPrice.toString()).multipliedBy(gasLimit).toFixed(0);
} else {
transaction.gasPrice = priority.gasPrice;
estimateGas = new BigN(priority.gasPrice).multipliedBy(transaction.gas).toFixed(0);
if (feeCombine.maxFeePerGas) {
const maxFee = new BigN(feeCombine.maxFeePerGas); // TODO: Need review

estimateGas = maxFee.multipliedBy(gasLimit).toFixed(0);
} else if (feeCombine.gasPrice) {
estimateGas = new BigN((feeCombine.gasPrice || 0)).multipliedBy(gasLimit).toFixed(0);
}
}
} catch (e) {
handleError((e as Error).message);
Expand Down
21 changes: 10 additions & 11 deletions packages/extension-base/src/core/logic-validation/transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ import { isBounceableAddress } from '@subwallet/extension-base/services/balance-
import { _TRANSFER_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
import { _EvmApi, _TonApi } from '@subwallet/extension-base/services/chain-service/types';
import { _getAssetDecimals, _getChainExistentialDeposit, _getChainNativeTokenBasicInfo, _getContractAddressOfToken, _getTokenMinAmount, _isNativeToken, _isTokenEvmSmartContract, _isTokenTonSmartContract } from '@subwallet/extension-base/services/chain-service/utils';
import { calculateGasFeeParams } from '@subwallet/extension-base/services/fee-service/utils';
import { isSubstrateTransaction, isTonTransaction } from '@subwallet/extension-base/services/transaction-service/helpers';
import { OptionalSWTransaction, SWTransactionInput, SWTransactionResponse } from '@subwallet/extension-base/services/transaction-service/types';
import { AccountSignMode, BasicTxErrorType, BasicTxWarningCode, TransferTxErrorType } from '@subwallet/extension-base/types';
import { balanceFormatter, formatNumber, pairToAccount } from '@subwallet/extension-base/utils';
import { AccountSignMode, BasicTxErrorType, BasicTxWarningCode, EvmEIP1559FeeOption, EvmFeeInfo, TransferTxErrorType } from '@subwallet/extension-base/types';
import { balanceFormatter, combineEthFee, formatNumber, pairToAccount } from '@subwallet/extension-base/utils';
import { isTonAddress } from '@subwallet/keyring';
import { KeyringPair } from '@subwallet/keyring/types';
import { keyring } from '@subwallet/ui-keyring';
Expand Down Expand Up @@ -370,7 +369,7 @@ export function checkSupportForTransaction (validationResponse: SWTransactionRes
}
}

export async function estimateFeeForTransaction (validationResponse: SWTransactionResponse, transaction: OptionalSWTransaction, chainInfo: _ChainInfo, evmApi: _EvmApi): Promise<FeeData> {
export async function estimateFeeForTransaction (validationResponse: SWTransactionResponse, transaction: OptionalSWTransaction, chainInfo: _ChainInfo, evmApi: _EvmApi, feeInfo: EvmFeeInfo): Promise<FeeData> {
const estimateFee: FeeData = {
symbol: '',
decimals: 0,
Expand All @@ -391,23 +390,23 @@ export async function estimateFeeForTransaction (validationResponse: SWTransacti
} else {
const gasLimit = transaction.gas || await evmApi.api.eth.estimateGas(transaction);

const priority = await calculateGasFeeParams(evmApi, chainInfo.slug);
const feeCombine = combineEthFee(feeInfo, validationResponse.feeOption, validationResponse.feeCustom as EvmEIP1559FeeOption);

if (transaction.maxFeePerGas) {
estimateFee.value = new BigN(transaction.maxFeePerGas.toString()).multipliedBy(gasLimit).toFixed(0);
} else if (transaction.gasPrice) {
estimateFee.value = new BigN((transaction.gasPrice || 0).toString()).multipliedBy(gasLimit).toFixed(0);
estimateFee.value = new BigN(transaction.gasPrice.toString()).multipliedBy(gasLimit).toFixed(0);
} else {
if (priority.baseGasFee) {
const maxFee = priority.maxFeePerGas; // TODO: Need review
if (feeCombine.maxFeePerGas) {
const maxFee = new BigN(feeCombine.maxFeePerGas); // TODO: Need review

estimateFee.value = maxFee.multipliedBy(gasLimit).toFixed(0);
} else {
estimateFee.value = new BigN(priority.gasPrice).multipliedBy(gasLimit).toFixed(0);
} else if (feeCombine.gasPrice) {
estimateFee.value = new BigN((feeCombine.gasPrice || 0)).multipliedBy(gasLimit).toFixed(0);
}
}

estimateFee.tooHigh = priority.busyNetwork;
estimateFee.tooHigh = feeInfo.busyNetwork;
}
} catch (e) {
const error = e as Error;
Expand Down
Loading
Loading