diff --git a/README.md b/README.md
index eb14117..b87b753 100644
--- a/README.md
+++ b/README.md
@@ -15,26 +15,29 @@ the Astria bridge.
* main application component
* define routes
* use context providers
-* `src/chainInfos` - Celestia and Astria chain information
-* `src/components` - React components
-* `src/contexts` - React context definitions
+* `src/components` - More general React components for the app, e.g. Navbar,
+ Dropdown, CopyToClipboardButton, etc
+* `src/config` - Configuration for the web app
+ * `src/config/chainConfigs` - Celestia and Astria chain information
+ * `src/config/contexts` - Config context and context provider
+ * `src/config/hooks` - Custom hook to make config easy to use
+ * `src/config/env.ts` - Environment variable definitions plus utilities for
+ consuming them
+ * `src/config/index.ts` - AppConfig and exports
+* `src/features` - Organizes components, contexts, hooks, services, types, and
+ utils for different features
+ * `src/features/EthWallet` - Used for interacting with EVM wallets
+ * `src/features/KeplrWallet` - User for interacting with Keplr wallet
+ * `src/features/Notifications` - Used for displaying notifications and toasts
* `src/pages`
* React components for each page
* `src/pages/Layout.tsx`
* page layout component using ``
* contains ``, ``
-* `src/providers` - React context provider definitions
-* `src/services`
- * api services
- * Keplr services
- * IBC services
- * 3rd party wrappers
* `src/styles`
* all style definitions
* using scss
* using [bulma](https://bulma.io/documentation/) css framework
-* `src/types` - type definitions
-* `src/utils` - utility functions
## Commands
@@ -53,19 +56,24 @@ just web build
* How to add new chain configs for a new environment (e.g. you want to add new
chain configs for "mainnet")
* create file that will contain the config values
+
```sh
touch web/src/config/chainConfigs/ChainConfigsMainnet.ts
```
+
* import new configs in
`astria-bridge-web-app/web/src/config/chainConfigs/index.ts`, while renaming
them
+
```typescript
import {
evmChains as mainnetEvmChains,
ibcChains as mainnetIbcChains,
} from "./ChainConfigsMainnet";
```
+
* add entry to `EVM_CHAIN_CONFIGS`
+
```typescript
const ENV_CHAIN_CONFIGS = {
local: { evm: localEvmChains, ibc: localIbcChains },
diff --git a/web/package.json b/web/package.json
index ec15acd..7b59f8e 100644
--- a/web/package.json
+++ b/web/package.json
@@ -1,6 +1,6 @@
{
"name": "astria-bridge-web-app",
- "version": "0.0.1",
+ "version": "0.10.0",
"private": true,
"dependencies": {
"@cosmjs/launchpad": "^0.27.1",
diff --git a/web/src/App.test.tsx b/web/src/App.test.tsx
index 2e16cf5..9a92a64 100644
--- a/web/src/App.test.tsx
+++ b/web/src/App.test.tsx
@@ -1,5 +1,4 @@
import type React from "react";
-import { screen } from "@testing-library/react";
import App from "./App";
import { renderWithRouter } from "testHelpers";
diff --git a/web/src/components/DepositCard/DepositCard.tsx b/web/src/components/DepositCard/DepositCard.tsx
index 85398b9..d789dbf 100644
--- a/web/src/components/DepositCard/DepositCard.tsx
+++ b/web/src/components/DepositCard/DepositCard.tsx
@@ -3,8 +3,8 @@ import { useEffect, useMemo, useState } from "react";
import { Dec, DecUtils } from "@keplr-wallet/unit";
import AnimatedArrowSpacer from "components/AnimatedDownArrowSpacer/AnimatedDownArrowSpacer";
-import Dropdown, { type DropdownOption } from "components/Dropdown/Dropdown";
-import { useConfig, type EvmChainInfo, type IbcChainInfo } from "config";
+import Dropdown from "components/Dropdown/Dropdown";
+import { useConfig } from "config";
import { useEvmChainSelection } from "features/EthWallet";
import { sendIbcTransfer, useIbcChainSelection } from "features/KeplrWallet";
import { useNotifications, NotificationType } from "features/Notifications";
@@ -18,55 +18,29 @@ export default function DepositCard(): React.ReactElement {
selectEvmChain,
evmChainsOptions,
selectedEvmChain,
+ selectedEvmChainOption,
+ defaultEvmCurrencyOption,
selectEvmCurrency,
evmCurrencyOptions,
evmBalance,
isLoadingEvmBalance,
connectEVMWallet,
} = useEvmChainSelection(evmChains);
- const defaultEvmCurrencyOption = useMemo(() => {
- return evmCurrencyOptions[0] || null;
- }, [evmCurrencyOptions]);
const {
ibcAccountAddress: fromAddress,
selectIbcChain,
ibcChainsOptions,
selectedIbcChain,
+ selectedIbcChainOption,
+ defaultIbcCurrencyOption,
selectIbcCurrency,
- ibcCurrencyOptions,
selectedIbcCurrency,
+ ibcCurrencyOptions,
ibcBalance,
isLoadingIbcBalance,
connectKeplrWallet,
} = useIbcChainSelection(ibcChains);
- const defaultIbcCurrencyOption = useMemo(() => {
- return ibcCurrencyOptions[0] || null;
- }, [ibcCurrencyOptions]);
-
- // selectedIbcChainOption allows us to ensure the label is set properly
- // in the dropdown when connecting via an "additional option"s action,
- // e.g. the "Connect Keplr Wallet" option in the dropdown
- const selectedIbcChainOption = useMemo(() => {
- if (!selectedIbcChain) {
- return null;
- }
- return {
- label: selectedIbcChain?.chainName || "",
- value: selectedIbcChain,
- leftIconClass: selectedIbcChain?.iconClass || "",
- } as DropdownOption;
- }, [selectedIbcChain]);
- const selectedEvmChainOption = useMemo(() => {
- if (!selectedEvmChain) {
- return null;
- }
- return {
- label: selectedEvmChain?.chainName || "",
- value: selectedEvmChain,
- leftIconClass: selectedEvmChain?.iconClass || "",
- } as DropdownOption;
- }, [selectedEvmChain]);
// the evm currency selection is controlled by the sender's chosen ibc currency,
// and should be updated when an ibc currency or evm chain is selected
diff --git a/web/src/components/WithdrawCard/WithdrawCard.tsx b/web/src/components/WithdrawCard/WithdrawCard.tsx
index 203c8d1..945794c 100644
--- a/web/src/components/WithdrawCard/WithdrawCard.tsx
+++ b/web/src/components/WithdrawCard/WithdrawCard.tsx
@@ -1,9 +1,9 @@
import type React from "react";
import { useEffect, useMemo, useState } from "react";
-import { useConfig, type EvmChainInfo, type IbcChainInfo } from "config";
+import { useConfig } from "config";
import AnimatedArrowSpacer from "components/AnimatedDownArrowSpacer/AnimatedDownArrowSpacer";
-import Dropdown, { type DropdownOption } from "components/Dropdown/Dropdown";
+import Dropdown from "components/Dropdown/Dropdown";
import {
getAstriaWithdrawerService,
useEthWallet,
@@ -22,6 +22,9 @@ export default function WithdrawCard(): React.ReactElement {
selectEvmChain,
evmChainsOptions,
selectedEvmChain,
+ selectedEvmChainOption,
+ withdrawFeeDisplay,
+ defaultEvmCurrencyOption,
selectEvmCurrency,
evmCurrencyOptions,
selectedEvmCurrency,
@@ -29,47 +32,20 @@ export default function WithdrawCard(): React.ReactElement {
isLoadingEvmBalance,
connectEVMWallet,
} = useEvmChainSelection(evmChains);
- const defaultEvmCurrencyOption = useMemo(() => {
- return evmCurrencyOptions[0] || null;
- }, [evmCurrencyOptions]);
const {
ibcAccountAddress: recipientAddress,
selectIbcChain,
ibcChainsOptions,
selectedIbcChain,
+ selectedIbcChainOption,
+ defaultIbcCurrencyOption,
selectIbcCurrency,
ibcCurrencyOptions,
ibcBalance,
isLoadingIbcBalance,
connectKeplrWallet,
} = useIbcChainSelection(ibcChains);
- const defaultIbcCurrencyOption = useMemo(() => {
- return ibcCurrencyOptions[0] || null;
- }, [ibcCurrencyOptions]);
-
- // selectedIbcChainOption allows us to ensure the label is set properly
- // in the dropdown when connecting via additional action
- const selectedIbcChainOption = useMemo(() => {
- if (!selectedIbcChain) {
- return null;
- }
- return {
- label: selectedIbcChain?.chainName || "",
- value: selectedIbcChain,
- leftIconClass: selectedIbcChain?.iconClass || "",
- } as DropdownOption;
- }, [selectedIbcChain]);
- const selectedEvmChainOption = useMemo(() => {
- if (!selectedEvmChain) {
- return null;
- }
- return {
- label: selectedEvmChain?.chainName || "",
- value: selectedEvmChain,
- leftIconClass: selectedEvmChain?.iconClass || "",
- } as DropdownOption;
- }, [selectedEvmChain]);
// the ibc currency selection is controlled by the sender's chosen evm currency,
// and should be updated when an ibc currency or ibc chain is selected
@@ -338,6 +314,11 @@ export default function WithdrawCard(): React.ReactElement {
Balance:
)}
+ {withdrawFeeDisplay && (
+
+ Withdrawal fee: {withdrawFeeDisplay}
+
+ )}
)}
diff --git a/web/src/config/chainConfigs/types.ts b/web/src/config/chainConfigs/types.ts
index 1da78f4..842663a 100644
--- a/web/src/config/chainConfigs/types.ts
+++ b/web/src/config/chainConfigs/types.ts
@@ -1,5 +1,4 @@
import type { ChainInfo } from "@keplr-wallet/types";
-import { ethers } from "ethers";
/**
* Represents information about an IBC chain.
diff --git a/web/src/config/contexts/ConfigContext.tsx b/web/src/config/contexts/ConfigContext.tsx
index 5be5ff1..f03ed66 100644
--- a/web/src/config/contexts/ConfigContext.tsx
+++ b/web/src/config/contexts/ConfigContext.tsx
@@ -1,11 +1,7 @@
import React from "react";
import type { AppConfig } from "config";
-import type {
- EvmChainInfo,
- EvmChains,
- IbcChains,
-} from "config/chainConfigs/types";
+import type { EvmChainInfo } from "config/chainConfigs/types";
import { getEnvChainConfigs } from "config/chainConfigs";
import { getEnvVariable } from "config/env";
diff --git a/web/src/features/EthWallet/hooks/useEvmChainSelection.tsx b/web/src/features/EthWallet/hooks/useEvmChainSelection.tsx
index 3093d7d..c649f09 100644
--- a/web/src/features/EthWallet/hooks/useEvmChainSelection.tsx
+++ b/web/src/features/EthWallet/hooks/useEvmChainSelection.tsx
@@ -5,6 +5,8 @@ import React, {
useRef,
useState,
} from "react";
+import { ethers } from "ethers";
+
import type { DropdownOption } from "components/Dropdown/Dropdown";
import {
type EvmChainInfo,
@@ -12,7 +14,7 @@ import {
type EvmCurrency,
evmCurrencyBelongsToChain,
} from "config";
-import { useNotifications, NotificationType } from "features/Notifications";
+import { NotificationType, useNotifications } from "features/Notifications";
import { useEthWallet } from "features/EthWallet/hooks/useEthWallet";
import EthWalletConnector from "features/EthWallet/components/EthWalletConnector/EthWalletConnector";
@@ -93,6 +95,18 @@ export function useEvmChainSelection(evmChains: EvmChains) {
evmAccountAddress,
]);
+ const selectedEvmChainNativeToken = useMemo(() => {
+ return selectedEvmChain?.currencies[0];
+ }, [selectedEvmChain]);
+
+ const withdrawFeeDisplay = useMemo(() => {
+ if (!selectedEvmChainNativeToken || !selectedEvmCurrency) {
+ return "";
+ }
+ const fee = ethers.formatUnits(selectedEvmCurrency.ibcWithdrawalFeeWei, 18);
+ return `${fee} ${selectedEvmChainNativeToken.coinDenom}`;
+ }, [selectedEvmChainNativeToken, selectedEvmCurrency]);
+
const evmChainsOptions = useMemo(() => {
return Object.entries(evmChains).map(
([chainLabel, chain]): DropdownOption => ({
@@ -103,6 +117,20 @@ export function useEvmChainSelection(evmChains: EvmChains) {
);
}, [evmChains]);
+ // selectedEvmChainOption allows us to ensure the label is set properly
+ // in the dropdown when connecting via an "additional option"s action,
+ // e.g. the "Connect Keplr Wallet" option in the dropdown
+ const selectedEvmChainOption = useMemo(() => {
+ if (!selectedEvmChain) {
+ return null;
+ }
+ return {
+ label: selectedEvmChain?.chainName || "",
+ value: selectedEvmChain,
+ leftIconClass: selectedEvmChain?.iconClass || "",
+ } as DropdownOption;
+ }, [selectedEvmChain]);
+
const selectEvmChain = useCallback((chain: EvmChainInfo | null) => {
setSelectedEvmChain(chain);
}, []);
@@ -112,7 +140,7 @@ export function useEvmChainSelection(evmChains: EvmChains) {
return [];
}
- // can only withdraw the currency if it has a withdraw contract address defined
+ // can only withdraw the currency if it has a withdrawer contract address defined
const withdrawableTokens = selectedEvmChain.currencies?.filter(
(currency) =>
currency.erc20ContractAddress ||
@@ -128,6 +156,10 @@ export function useEvmChainSelection(evmChains: EvmChains) {
);
}, [selectedEvmChain]);
+ const defaultEvmCurrencyOption = useMemo(() => {
+ return evmCurrencyOptions[0] || null;
+ }, [evmCurrencyOptions]);
+
const selectEvmCurrency = useCallback((currency: EvmCurrency) => {
setSelectedEvmCurrency(currency);
}, []);
@@ -191,7 +223,11 @@ export function useEvmChainSelection(evmChains: EvmChains) {
selectEvmCurrency,
selectedEvmChain,
+ selectedEvmChainNativeToken,
+ withdrawFeeDisplay,
selectedEvmCurrency,
+ defaultEvmCurrencyOption,
+ selectedEvmChainOption,
evmAccountAddress,
evmBalance,
diff --git a/web/src/features/KeplrWallet/hooks/useIbcChainSelection.tsx b/web/src/features/KeplrWallet/hooks/useIbcChainSelection.tsx
index d98bc49..aa490a9 100644
--- a/web/src/features/KeplrWallet/hooks/useIbcChainSelection.tsx
+++ b/web/src/features/KeplrWallet/hooks/useIbcChainSelection.tsx
@@ -115,6 +115,24 @@ export function useIbcChainSelection(ibcChains: IbcChains) {
);
}, [selectedIbcChain]);
+ const defaultIbcCurrencyOption = useMemo(() => {
+ return ibcCurrencyOptions[0] || null;
+ }, [ibcCurrencyOptions]);
+
+ // selectedIbcChainOption allows us to ensure the label is set properly
+ // in the dropdown when connecting via an "additional option"s action,
+ // e.g. the "Connect Keplr Wallet" option in the dropdown
+ const selectedIbcChainOption = useMemo(() => {
+ if (!selectedIbcChain) {
+ return null;
+ }
+ return {
+ label: selectedIbcChain?.chainName || "",
+ value: selectedIbcChain,
+ leftIconClass: selectedIbcChain?.iconClass || "",
+ } as DropdownOption;
+ }, [selectedIbcChain]);
+
const selectIbcCurrency = useCallback((currency: IbcCurrency) => {
setSelectedIbcCurrency(currency);
}, []);
@@ -192,6 +210,8 @@ export function useIbcChainSelection(ibcChains: IbcChains) {
selectedIbcChain,
selectedIbcCurrency,
+ defaultIbcCurrencyOption,
+ selectedIbcChainOption,
ibcAccountAddress,
ibcBalance,
diff --git a/web/src/styles/icons.scss b/web/src/styles/icons.scss
index 6210d22..3510531 100644
--- a/web/src/styles/icons.scss
+++ b/web/src/styles/icons.scss
@@ -48,7 +48,6 @@ i.i-flame {
}
i.i-noble {
- // this was downloaded from figma
background-image: url('https://avatars.githubusercontent.com/u/133800472?s=200&v=4');
background-repeat: no-repeat;
background-size: contain;