Skip to content

Commit

Permalink
fix asset metadata for fee estimation (#1468)
Browse files Browse the repository at this point in the history
* proper fee estimation asset denom

* attempt to pass ci

* remove todo

* nullish coalescing operator

* comments
  • Loading branch information
TalDerei authored Jul 18, 2024
1 parent 15a1afc commit 6a41854
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 10 deletions.
2 changes: 2 additions & 0 deletions apps/minifront/src/components/send/send-form/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const SendForm = () => {
memo,
fee,
feeTier,
assetFeeMetadata,
setAmount,
setSelection,
setRecipient,
Expand Down Expand Up @@ -97,6 +98,7 @@ export const SendForm = () => {
feeTier={feeTier}
stakingAssetMetadata={stakingTokenMetadata.data}
setFeeTier={setFeeTier}
assetFeeMetadata={assetFeeMetadata}
/>

<InputBlock
Expand Down
14 changes: 7 additions & 7 deletions apps/minifront/src/components/shared/gas-fee.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {
Fee,
FeeTier_Tier,
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/fee/v1/fee_pb.js';
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/fee/v1/fee_pb';
import { SegmentedPicker, SegmentedPickerOption } from '@repo/ui/components/ui/segmented-picker';
import { InputBlock } from './input-block';
import { ValueViewComponent } from '@repo/ui/components/ui/value';
import {
Metadata,
ValueView,
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1/asset_pb.js';
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1/asset_pb';

const FEE_TIER_OPTIONS: SegmentedPickerOption<FeeTier_Tier>[] = [
{
Expand All @@ -30,23 +30,23 @@ export const GasFee = ({
feeTier,
stakingAssetMetadata,
setFeeTier,
assetFeeMetadata,
}: {
fee: Fee | undefined;
feeTier: FeeTier_Tier;
stakingAssetMetadata?: Metadata;
assetFeeMetadata?: Metadata;
setFeeTier: (feeTier: FeeTier_Tier) => void;
}) => {
if (!stakingAssetMetadata) {
return null;
}
// If the metadata for the fee asset is undefined, fallback to using the bundled staking asset metadata.
const feeMetadata = assetFeeMetadata ?? stakingAssetMetadata;

const feeValueView = new ValueView({
valueView: {
case: 'knownAssetId',
value: {
amount: fee?.amount ?? { hi: 0n, lo: 0n },
// TODO: once https://github.com/penumbra-zone/web/pull/1468 is merged, change this to metadata: assetFeeMedata
metadata: stakingAssetMetadata,
metadata: feeMetadata,
},
},
});
Expand Down
15 changes: 15 additions & 0 deletions apps/minifront/src/fetchers/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Chain, ChainRegistryClient, Registry } from '@penumbra-labs/registry';
import { useQuery } from '@tanstack/react-query';
import { getChainId } from './chain-id';
import { getAssetMetadataById } from './assets';
import { AssetId } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1/asset_pb';

export const chainRegistryClient = new ChainRegistryClient();

Expand Down Expand Up @@ -34,6 +35,20 @@ export const getStakingTokenMetadata = async () => {
return stakingAssetsMetadata;
};

export const getAssetTokenMetadata = async (assetId: AssetId) => {
const chainId = await getChainId();
if (!chainId) {
throw new Error('Could not fetch chain id');
}

const assetTokenMetadata = await getAssetMetadataById(assetId);

if (!assetTokenMetadata) {
throw new Error('Could not fetch asset token metadata');
}
return assetTokenMetadata;
};

export const getChains = async (): Promise<Chain[]> => {
const chainId = await getChainId();
if (!chainId) {
Expand Down
17 changes: 14 additions & 3 deletions apps/minifront/src/state/send/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import {
TransactionPlannerRequest,
TransactionPlannerRequest_Output,
TransactionPlannerRequest_Spend,
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/view/v1/view_pb.js';
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/view/v1/view_pb';
import { BigNumber } from 'bignumber.js';
import { MemoPlaintext } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/transaction/v1/transaction_pb.js';
import { MemoPlaintext } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/transaction/v1/transaction_pb';
import { amountMoreThanBalance, plan, planBuildBroadcast } from '../helpers';

import {
Fee,
FeeTier_Tier,
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/fee/v1/fee_pb.js';
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/fee/v1/fee_pb';
import {
getAssetIdFromValueView,
getDisplayDenomExponentFromValueView,
Expand All @@ -23,6 +23,8 @@ import { toBaseUnit } from '@penumbra-zone/types/lo-hi';
import { isAddress } from '@penumbra-zone/bech32m/penumbra';
import { transferableBalancesResponsesSelector } from './helpers';
import { PartialMessage } from '@bufbuild/protobuf';
import { Metadata } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1/asset_pb';
import { getAssetTokenMetadata } from '../../fetchers/registry';

export interface SendSlice {
selection: BalancesResponse | undefined;
Expand All @@ -41,6 +43,7 @@ export interface SendSlice {
txInProgress: boolean;
isSendingMax: boolean;
setIsSendingMax: (isSendingMax: boolean) => void;
assetFeeMetadata: Metadata | undefined;
}

export const createSendSlice = (): SliceCreator<SendSlice> => (set, get) => {
Expand All @@ -53,6 +56,7 @@ export const createSendSlice = (): SliceCreator<SendSlice> => (set, get) => {
feeTier: FeeTier_Tier.LOW,
txInProgress: false,
isSendingMax: false,
assetFeeMetadata: undefined,
setAmount: amount => {
set(state => {
state.send.amount = amount;
Expand Down Expand Up @@ -84,18 +88,25 @@ export const createSendSlice = (): SliceCreator<SendSlice> => (set, get) => {
if (!amount || !recipient || !selection) {
set(state => {
state.send.fee = undefined;
state.send.assetFeeMetadata = undefined;
});
return;
}

const txPlan = await plan(assembleRequest(get().send));
const fee = txPlan.transactionParameters?.fee;

// Fetch the asset metadata for the fee if assetId is defined; otherwise, set it to undefined.
// The undefined case occurs when the fee uses the native staking token.
const feeAssetMetadata = fee?.assetId ? await getAssetTokenMetadata(fee.assetId) : undefined;

if (!fee?.amount) {
return;
}

set(state => {
state.send.fee = fee;
state.send.assetFeeMetadata = feeAssetMetadata;
});
},
setFeeTier: feeTier => {
Expand Down

0 comments on commit 6a41854

Please sign in to comment.