From 46479dcbdd40a3d149967ede74b73d6a92cbec2a Mon Sep 17 00:00:00 2001 From: Gabe Rodriguez Date: Tue, 19 Mar 2024 15:00:52 +0000 Subject: [PATCH] Tx details --- .../src/components/header/constants.tsx | 2 +- .../src/components/ibc/ibc-loader.ts | 8 ++- apps/minifront/src/components/ibc/layout.tsx | 4 -- apps/minifront/src/state/ibc.test.ts | 4 +- apps/minifront/src/state/ibc.ts | 5 +- .../perspective/transaction/classification.ts | 4 +- packages/perspective/transaction/classify.ts | 3 ++ .../perspective/transaction/perspective.ts | 1 + packages/transport-chrome/session-manager.ts | 8 +-- packages/types/src/registry.ts | 5 +- .../ui/components/ui/tx/view/action-view.tsx | 3 +- .../ui/tx/view/isc20-withdrawal.tsx | 51 +++++++++++++++++++ 12 files changed, 81 insertions(+), 17 deletions(-) create mode 100644 packages/ui/components/ui/tx/view/isc20-withdrawal.tsx diff --git a/apps/minifront/src/components/header/constants.tsx b/apps/minifront/src/components/header/constants.tsx index 17d569a641..1b51439667 100644 --- a/apps/minifront/src/components/header/constants.tsx +++ b/apps/minifront/src/components/header/constants.tsx @@ -41,7 +41,7 @@ export const headerLinks: HeaderLink[] = [ { href: PagePath.IBC, label: 'IBC', - active: true, + active: false, mobileIcon: , }, ]; diff --git a/apps/minifront/src/components/ibc/ibc-loader.ts b/apps/minifront/src/components/ibc/ibc-loader.ts index 6d5ce94cba..a6b91c58c1 100644 --- a/apps/minifront/src/components/ibc/ibc-loader.ts +++ b/apps/minifront/src/components/ibc/ibc-loader.ts @@ -3,6 +3,7 @@ import { testnetIbcChains } from '@penumbra-zone/constants/src/chains'; import { BalancesResponse } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/view/v1/view_pb'; import { getBalances } from '../../fetchers/balances'; import { useStore } from '../../state'; +import { filterBalancesPerChain } from '../../state/ibc'; export type IbcLoaderResponse = BalancesResponse[]; @@ -10,10 +11,13 @@ export const IbcLoader: LoaderFunction = async (): Promise => const assetBalances = await getBalances(); if (assetBalances[0]) { + const initialChain = testnetIbcChains[0]; + const initialSelection = filterBalancesPerChain(assetBalances, initialChain)[0]; + // set initial account if accounts exist and asset if account has asset list useStore.setState(state => { - state.ibc.selection = assetBalances[0]; - state.ibc.chain = testnetIbcChains[0]; + state.ibc.selection = initialSelection; + state.ibc.chain = initialChain; }); } diff --git a/apps/minifront/src/components/ibc/layout.tsx b/apps/minifront/src/components/ibc/layout.tsx index f587958187..cd958dfc8c 100644 --- a/apps/minifront/src/components/ibc/layout.tsx +++ b/apps/minifront/src/components/ibc/layout.tsx @@ -1,10 +1,6 @@ import { IbcInForm } from './ibc-in-form'; import { IbcOutForm } from './ibc-out-form'; -//
-// -// className='absolute inset-x-0 top-[-75px] z-0 mx-auto h-[141px] w-[136px] rotate-[320deg] md:left-[-100px] md:top-[-140px] md:mx-0 md:size-[234px]' - export const IbcLayout = () => { return (
diff --git a/apps/minifront/src/state/ibc.test.ts b/apps/minifront/src/state/ibc.test.ts index 47a6036945..ec58bd3300 100644 --- a/apps/minifront/src/state/ibc.test.ts +++ b/apps/minifront/src/state/ibc.test.ts @@ -13,8 +13,6 @@ import { produce } from 'immer'; import { BalancesResponse } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/view/v1/view_pb'; import { bech32ToAddress } from '@penumbra-zone/bech32'; -// TODO: Revisit tests when re-implementing ibc form - describe.skip('IBC Slice', () => { const selectionExample = new BalancesResponse({ balanceView: new ValueView({ @@ -94,6 +92,8 @@ describe.skip('IBC Slice', () => { chainId: 'osmosis-test-5', ibcChannel: 'channel-0', iconUrl: '/test.svg', + nativeAssets: [], + addressPrefix: 'osmo', } satisfies Chain; useStore.getState().ibc.setChain(chain); diff --git a/apps/minifront/src/state/ibc.ts b/apps/minifront/src/state/ibc.ts index 1633eb1064..2ba3c85326 100644 --- a/apps/minifront/src/state/ibc.ts +++ b/apps/minifront/src/state/ibc.ts @@ -21,6 +21,7 @@ import { IbcLoaderResponse } from '../components/ibc/ibc-loader'; import { getAssetId } from '@penumbra-zone/getters/src/metadata'; import { STAKING_TOKEN_METADATA } from '@penumbra-zone/constants/src/assets'; import { bech32IsValid } from '@penumbra-zone/bech32'; +import { errorToast } from '@penumbra-zone/ui'; export interface IbcSendSlice { selection: BalancesResponse | undefined; @@ -69,12 +70,14 @@ export const createIbcSendSlice = (): SliceCreator => (set, get) = try { const req = await getPlanRequest(get().ibc); - await planBuildBroadcast('unknown', req); + await planBuildBroadcast('ics20Withdrawal', req); // Reset form set(state => { state.ibc.amount = ''; }); + } catch (e) { + errorToast(e, 'Ics20 withdrawal error').render(); } finally { set(state => { state.ibc.txInProgress = false; diff --git a/packages/perspective/transaction/classification.ts b/packages/perspective/transaction/classification.ts index 6826faafd1..44e7ecbc8a 100644 --- a/packages/perspective/transaction/classification.ts +++ b/packages/perspective/transaction/classification.ts @@ -18,4 +18,6 @@ export type TransactionClassification = /** The transaction contains an `undelegate` action. */ | 'undelegate' /** The transaction contains an `undelegateClaim` action. */ - | 'undelegateClaim'; + | 'undelegateClaim' + /** The transaction contains an `ics20Withdrawal` action. */ + | 'ics20Withdrawal'; diff --git a/packages/perspective/transaction/classify.ts b/packages/perspective/transaction/classify.ts index dc9d2eec76..3eea0182af 100644 --- a/packages/perspective/transaction/classify.ts +++ b/packages/perspective/transaction/classify.ts @@ -13,6 +13,8 @@ export const classifyTransaction = (txv?: TransactionView): TransactionClassific if (txv.bodyView?.actionViews.some(a => a.actionView.case === 'undelegate')) return 'undelegate'; if (txv.bodyView?.actionViews.some(a => a.actionView.case === 'undelegateClaim')) return 'undelegateClaim'; + if (txv.bodyView?.actionViews.some(a => a.actionView.case === 'ics20Withdrawal')) + return 'ics20Withdrawal'; const hasOpaqueSpend = txv.bodyView?.actionViews.some( a => a.actionView.case === 'spend' && a.actionView.value.spendView.case === 'opaque', @@ -85,6 +87,7 @@ export const TRANSACTION_LABEL_BY_CLASSIFICATION: Record diff --git a/packages/perspective/transaction/perspective.ts b/packages/perspective/transaction/perspective.ts index a6abe0b686..f663895aa7 100644 --- a/packages/perspective/transaction/perspective.ts +++ b/packages/perspective/transaction/perspective.ts @@ -77,6 +77,7 @@ export const viewActionFromEmptyPerspective = (action: Action): ActionView | und }), }, }); + case 'ics20Withdrawal': case 'delegate': case 'undelegate': return new ActionView({ diff --git a/packages/transport-chrome/session-manager.ts b/packages/transport-chrome/session-manager.ts index 88bd45b6ef..7d3039b6e1 100644 --- a/packages/transport-chrome/session-manager.ts +++ b/packages/transport-chrome/session-manager.ts @@ -102,11 +102,13 @@ export class CRSessionManager { port.onMessage.addListener((i, p) => { void (async () => { try { - if (isTransportMessage(i)) + if (isTransportMessage(i)) { p.postMessage(await this.clientMessageHandler(session.acont.signal, i)); - else if (isTransportInitChannel(i)) + } else if (isTransportInitChannel(i)) { console.warn('Client streaming unimplemented', this.acceptChannelStreamRequest(i)); - else console.warn('Unknown item in transport', i); + } else { + console.warn('Unknown item in transport', i); + } } catch (e) { session.acont.abort(e); } diff --git a/packages/types/src/registry.ts b/packages/types/src/registry.ts index 0611a89da5..73034e6688 100644 --- a/packages/types/src/registry.ts +++ b/packages/types/src/registry.ts @@ -13,6 +13,7 @@ import { CustodyService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumb import { TendermintProxyService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/util/tendermint_proxy/v1/tendermint_proxy_connect'; import { ViewService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/view/v1/view_connect'; import { createRegistry, IMessageTypeRegistry } from '@bufbuild/protobuf'; +import { ClientState } from '@buf/cosmos_ibc.bufbuild_es/ibc/lightclients/tendermint/v1/tendermint_pb'; /** * This type registry is for JSON serialization of protobuf messages. @@ -30,13 +31,13 @@ export const typeRegistry: IMessageTypeRegistry = createRegistry( CustodyService, ViewService, - IbcQueryService, - AppService, + ClientState, CompactBlockService, DexService, DexSimulationService, GovernanceService, + IbcQueryService, SctService, ShieldedPoolService, StakeService, diff --git a/packages/ui/components/ui/tx/view/action-view.tsx b/packages/ui/components/ui/tx/view/action-view.tsx index 6e2a7def15..1e696bf1be 100644 --- a/packages/ui/components/ui/tx/view/action-view.tsx +++ b/packages/ui/components/ui/tx/view/action-view.tsx @@ -7,6 +7,7 @@ import { SwapClaimViewComponent } from './swap-claim'; import { DelegateComponent } from './delegate'; import { UndelegateComponent } from './undelegate'; import { UndelegateClaimComponent } from './undelegate-claim'; +import { Ics20WithdrawalComponent } from './isc20-withdrawal'; const CASE_TO_LABEL: Record = { daoDeposit: 'DAO Deposit', @@ -55,7 +56,7 @@ export const ActionViewComponent = ({ av: { actionView } }: { av: ActionView }) return ; case 'ics20Withdrawal': - return ; + return ; case 'delegate': return ; diff --git a/packages/ui/components/ui/tx/view/isc20-withdrawal.tsx b/packages/ui/components/ui/tx/view/isc20-withdrawal.tsx new file mode 100644 index 0000000000..dd954735c1 --- /dev/null +++ b/packages/ui/components/ui/tx/view/isc20-withdrawal.tsx @@ -0,0 +1,51 @@ +import { Ics20Withdrawal } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/ibc/v1/ibc_pb'; +import { ViewBox } from './viewbox'; +import { ActionDetails } from './action-details'; +import { joinLoHiAmount } from '@penumbra-zone/types/src/amount'; +import { bech32Address } from '@penumbra-zone/bech32'; + +export const Ics20WithdrawalComponent = ({ value }: { value: Ics20Withdrawal }) => { + return ( + + {value.denom && {value.denom.denom}} + + {value.amount && ( + + {joinLoHiAmount(value.amount).toString()} + + )} + + + {value.destinationChainAddress} + + + {value.sourceChannel} + + {value.returnAddress && ( + + {bech32Address(value.returnAddress)} + + )} + + {value.timeoutHeight && ( + <> + + {value.timeoutHeight.revisionHeight.toString()} + + + {value.timeoutHeight.revisionNumber.toString()} + + + )} + + + {new Date(Number(value.timeoutTime)).toString()} + + + } + /> + ); +};