Skip to content

Commit

Permalink
Merge pull request #35 from astriaorg/develop
Browse files Browse the repository at this point in the history
Release 10/24/24-1
  • Loading branch information
steezeburger authored Oct 24, 2024
2 parents a500688 + 85718a9 commit 4b755a7
Show file tree
Hide file tree
Showing 30 changed files with 239 additions and 139 deletions.
5 changes: 5 additions & 0 deletions web/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ REACT_APP_VERSION=$npm_package_version
REACT_APP_IBC_CHAINS=
# can set custom evm chains via json string
REACT_APP_EVM_CHAINS=

REACT_APP_BRAND_URL=https://astria.org
REACT_APP_BRIDGE_URL=https://bridge.astria.org
REACT_APP_SWAP_URL=https://flame.astria.org/swap
REACT_APP_POOL_URL=https://flame.astria.org/pool
5 changes: 5 additions & 0 deletions web/.env.test
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ REACT_APP_ENV=test

REACT_APP_IBC_CHAINS='{"Celestia Mocha-4":{"chainId":"mocha-4","chainName":"Celestia Mocha-4","rpc":"wss://rpc-mocha.pops.one","rest":"https://api-mocha.pops.one","stakeCurrency":{"coinDenom":"TIA","coinMinimalDenom":"utia","coinDecimals":6},"bip44":{"coinType":118},"bech32Config":{"bech32PrefixAccAddr":"celestia","bech32PrefixAccPub":"celestiapub","bech32PrefixConsAddr":"celestiavalcons","bech32PrefixConsPub":"celestiavalconspub","bech32PrefixValAddr":"celestiavaloper","bech32PrefixValPub":"celestiavaloperpub"},"currencies":[{"coinDenom":"TIA","coinMinimalDenom":"utia","coinDecimals":6,"ibcChannel":"channel-128","sequencerBridgeAccount":"astria1d7zjjljc0dsmxa545xkpwxym86g8uvvwhtezcr","iconClass":"i-celestia"},{"coinDenom":"STEEZE","coinMinimalDenom":"usteeze","coinDecimals":6}],"feeCurrencies":[{"coinDenom":"TIA","coinMinimalDenom":"utia","coinDecimals":6,"gasPriceStep":{"low":0.01,"average":0.02,"high":0.1}}],"iconClass":"i-celestia"}}'
REACT_APP_EVM_CHAINS=''

REACT_APP_BRAND_URL=https://astria.org
REACT_APP_BRIDGE_URL=https://bridge.astria.org
REACT_APP_SWAP_URL=https://flame.astria.org/swap
REACT_APP_POOL_URL=https://flame.astria.org/pool
6 changes: 3 additions & 3 deletions web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type React from "react";
import { Route, Routes } from "react-router-dom";
import { EthWalletContextProvider } from "features/EthWallet/contexts/EthWalletContext";
import BridgePage from "pages/BridgePage/BridgePage";
import Layout from "pages/Layout";
import { NotificationsContextProvider } from "features/Notifications/contexts/NotificationsContext";
import { ConfigContextProvider } from "config/contexts/ConfigContext";
import { ConfigContextProvider } from "config";
import { EthWalletContextProvider } from "features/EthWallet";
import { NotificationsContextProvider } from "features/Notifications";

/**
* App component with routes.
Expand Down
14 changes: 6 additions & 8 deletions web/src/components/DepositCard/DepositCard.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import type React from "react";
import { useContext, useEffect, useMemo, useState } from "react";
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 type { EvmChainInfo, IbcChainInfo } from "config/chainConfigs";
import { useConfig } from "config/hooks/useConfig";
import { NotificationType } from "features/Notifications/components/Notification/types";
import { NotificationsContext } from "features/Notifications/contexts/NotificationsContext";
import { useEvmChainSelection } from "features/EthWallet/hooks/useEvmChainSelection";
import { useIbcChainSelection } from "features/IbcChainSelector/hooks/useIbcChainSelection";
import { useConfig, type EvmChainInfo, type IbcChainInfo } from "config";
import { useEvmChainSelection } from "features/EthWallet";
import { useIbcChainSelection } from "features/IbcChainSelector";
import { useNotifications, NotificationType } from "features/Notifications";
import { sendIbcTransfer } from "services/ibc";

export default function DepositCard(): React.ReactElement {
const { addNotification } = useContext(NotificationsContext);
const { evmChains, ibcChains } = useConfig();
const { addNotification } = useNotifications();

const {
evmAccountAddress: recipientAddress,
Expand Down
10 changes: 10 additions & 0 deletions web/src/components/Navbar/Navbar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,14 @@ describe("Navbar Component", () => {
const logoElem = screen.getByAltText(/logo/i);
expect(logoElem).toBeInTheDocument();
});

test("renders navbar links", () => {
renderWithRouter(<Navbar />);
const bridgeLink = screen.getByText(/bridge/i);
expect(bridgeLink).toBeInTheDocument();
const swapLink = screen.getByText(/swap/i);
expect(swapLink).toBeInTheDocument();
const poolLink = screen.getByText(/pool/i);
expect(poolLink).toBeInTheDocument();
});
});
24 changes: 15 additions & 9 deletions web/src/components/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import type React from "react";
import { useState } from "react";
import { Link } from "react-router-dom";
import logo from "../../logo-flame-w-text.svg";

import { useConfig } from "config";
import logo from "logo-flame-w-text.svg";

function Navbar() {
const [isMobileMenuActive, setIsMobileMenuActive] = useState(false);
Expand All @@ -10,19 +12,22 @@ function Navbar() {
setIsMobileMenuActive((prev) => !prev);
};

const brandLink = "https://www.astria.org/";
const swapLink = "https://flame.astria.org/";
const poolLink = "https://flame.astria.org/";
const { brandURL, bridgeURL, swapURL, poolURL } = useConfig();

return (
<nav
className="navbar is-spaced is-transparent"
aria-label="main navigation"
>
<div className="navbar-brand">
<Link className="navbar-item" to={brandLink}>
<a
target="_blank"
href={brandURL}
className="navbar-item"
rel="noreferrer"
>
<img src={logo} width="161" height="32" alt="logo" />
</Link>
</a>
<button
type="button"
className={`navbar-burger ${isMobileMenuActive && "is-active"}`}
Expand All @@ -44,20 +49,21 @@ function Navbar() {
}`}
>
<div className="navbar-middle has-text-weight-medium is-family-monospace">
<Link to="/" className="navbar-item">
{/* this link is always active right now since the bridge is a separate app */}
<Link to="/" className="navbar-item is-active">
BRIDGE
</Link>
<a
target="_blank"
href={swapLink}
href={swapURL}
className="navbar-item"
rel="noreferrer"
>
SWAP
</a>
<a
target="_blank"
href={poolLink}
href={poolURL}
className="navbar-item"
rel="noreferrer"
>
Expand Down
20 changes: 10 additions & 10 deletions web/src/components/WithdrawCard/WithdrawCard.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import type React from "react";
import { useContext, useEffect, useMemo, useState } from "react";
import { useEffect, useMemo, useState } from "react";

import { useConfig, type EvmChainInfo, type IbcChainInfo } from "config";
import AnimatedArrowSpacer from "components/AnimatedDownArrowSpacer/AnimatedDownArrowSpacer";
import Dropdown, { type DropdownOption } from "components/Dropdown/Dropdown";
import type { EvmChainInfo, IbcChainInfo } from "config/chainConfigs";
import { useConfig } from "config/hooks/useConfig";
import {
getAstriaWithdrawerService,
useEthWallet,
useEvmChainSelection,
} from "features/EthWallet";
import { useIbcChainSelection } from "features/IbcChainSelector";
import { getAstriaWithdrawerService } from "features/EthWallet";
import { useEthWallet } from "features/EthWallet/hooks/useEthWallet";
import { useEvmChainSelection } from "features/EthWallet/hooks/useEvmChainSelection";
import { NotificationType } from "features/Notifications/components/Notification/types";
import { NotificationsContext } from "features/Notifications/contexts/NotificationsContext";
import { NotificationType, useNotifications } from "features/Notifications";

export default function WithdrawCard(): React.ReactElement {
const { addNotification } = useContext(NotificationsContext);
const { selectedWallet } = useEthWallet();
const { evmChains, ibcChains } = useConfig();
const { addNotification } = useNotifications();
const { selectedWallet } = useEthWallet();

const {
evmAccountAddress: fromAddress,
Expand Down
5 changes: 3 additions & 2 deletions web/src/config/chainConfigs/ChainConfigsLocal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ const NobleChainInfo: IbcChainInfo = {
chainId: "noble-local-0",
chainName: "noble-local-0",
// RPC endpoint of the chain
rpc: "http://rpc.app.celestia.localdev.me",
rpc: "http://rpc.app.noble.localdev.me",
// REST endpoint of the chain.
rest: "http://rest.app.celestia.localdev.me",
rest: "http://rest.app.noble.localdev.me",
// Staking coin information
stakeCurrency: {
// Coin denomination to be displayed to the user.
Expand Down Expand Up @@ -213,6 +213,7 @@ const FakeChainInfo: EvmChainInfo = {
coinDenom: "FAKE",
coinMinimalDenom: "ufake",
coinDecimals: 6,
// fake address here so it shows up in the currency dropdown
nativeTokenWithdrawerContractAddress:
"0x0000000000000000000000000000000000000000",
iconClass: "i-flame",
Expand Down
18 changes: 1 addition & 17 deletions web/src/config/chainConfigs/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ChainInfo } from "@keplr-wallet/types";
import { getEnvVariable } from "config/env";
import { getEnvVariable } from "config";

import {
evmChains as localEvmChains,
Expand Down Expand Up @@ -155,22 +155,6 @@ export type EvmChains = {
[label: string]: EvmChainInfo;
};

/**
* Retrieves the EVM chain with the given chain ID.
*
* @param chainIdHex - The chain ID as a hexadecimal string.
*/
export function getEvmChainById(chainIdHex: string): EvmChainInfo {
const chainId = Number.parseInt(chainIdHex as string, 16);
const chains = getEvmChains();
for (const chain of Object.values(chains)) {
if (chain.chainId === chainId) {
return chain;
}
}
throw new Error(`Chain with ID ${chainId} (hex: ${chainIdHex}) not found`);
}

/**
* Retrieves the EVM chains from the environment variable override or the default chain configurations,
* depending on the environment.
Expand Down
5 changes: 3 additions & 2 deletions web/src/config/contexts/ConfigContext.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type React from "react";
import { render, screen } from "@testing-library/react";
import { ConfigContextProvider } from "./ConfigContext";
import { useConfig } from "../hooks/useConfig";

import { ConfigContextProvider } from "config/contexts/ConfigContext";
import { useConfig } from "config/hooks/useConfig";

const TestComponent: React.FC = () => {
const config = useConfig();
Expand Down
46 changes: 39 additions & 7 deletions web/src/config/contexts/ConfigContext.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import React from "react";
import React, { useMemo } from "react";

import type { AppConfig } from "..";
import type { AppConfig } from "config";
import {
type EvmChainInfo,
type EvmChains,
getEvmChains,
getIbcChains,
type IbcChains,
} from "../chainConfigs";
} from "config/chainConfigs";
import { getEnvVariable } from "config/env";

export const ConfigContext = React.createContext<AppConfig | undefined>(
undefined,
Expand All @@ -17,17 +19,47 @@ type ConfigContextProps = {
};

/**
* ConfigContextProvider component to provide notifications context to children.
* ConfigContextProvider component to provide config context to children.
* @param children
*/
export const ConfigContextProvider: React.FC<ConfigContextProps> = ({
children,
}) => {
const ibcChains: IbcChains = getIbcChains();
const evmChains: EvmChains = getEvmChains();
const evmChains: EvmChains = useMemo(() => {
return getEvmChains();
}, []);
const ibcChains: IbcChains = useMemo(() => {
return getIbcChains();
}, []);

const brandURL = getEnvVariable("REACT_APP_BRAND_URL");
const bridgeURL = getEnvVariable("REACT_APP_BRIDGE_URL");
const swapURL = getEnvVariable("REACT_APP_SWAP_URL");
const poolURL = getEnvVariable("REACT_APP_POOL_URL");

// retrieves the EVM chain with the given chain ID.
const getEvmChainById = (chainIdHex: string): EvmChainInfo => {
const chainIdNum = Number.parseInt(chainIdHex, 16);
for (const chain of Object.values(evmChains)) {
if (chain.chainId === chainIdNum) {
return chain;
}
}
throw new Error(`Chain with ID ${chainIdHex} (${chainIdNum}) not found`);
};

return (
<ConfigContext.Provider value={{ ibcChains, evmChains }}>
<ConfigContext.Provider
value={{
ibcChains,
evmChains,
brandURL,
bridgeURL,
swapURL,
poolURL,
getEvmChainById,
}}
>
{children}
</ConfigContext.Provider>
);
Expand Down
4 changes: 4 additions & 0 deletions web/src/config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ export const ENV = {
REACT_APP_VERSION: process.env.REACT_APP_VERSION,
REACT_APP_IBC_CHAINS: process.env.REACT_APP_IBC_CHAINS,
REACT_APP_EVM_CHAINS: process.env.REACT_APP_EVM_CHAINS,
REACT_APP_BRAND_URL: process.env.REACT_APP_BRAND_URL,
REACT_APP_BRIDGE_URL: process.env.REACT_APP_BRIDGE_URL,
REACT_APP_SWAP_URL: process.env.REACT_APP_SWAP_URL,
REACT_APP_POOL_URL: process.env.REACT_APP_POOL_URL,
};

/**
Expand Down
2 changes: 1 addition & 1 deletion web/src/config/hooks/useConfig.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useContext } from "react";

import { ConfigContext } from "../contexts/ConfigContext";
import { ConfigContext } from "config/contexts/ConfigContext";

/**
* Hook to use the config context.
Expand Down
40 changes: 39 additions & 1 deletion web/src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,51 @@
import type { EvmChains, IbcChains } from "./chainConfigs";
import {
type EvmChainInfo,
type EvmChains,
type EvmCurrency,
evmCurrencyBelongsToChain,
type IbcChainInfo,
type IbcChains,
type IbcCurrency,
ibcCurrencyBelongsToChain,
toChainInfo,
} from "./chainConfigs";
import { ConfigContextProvider } from "./contexts/ConfigContext";
import { getEnvVariable } from "./env";
import { useConfig } from "./hooks/useConfig";

/**
* Represents the configuration object for the application.
*
* @typedef {Object} AppConfig
* @property {IbcChains} ibcChains - The configurations for IBC chains.
* @property {EvmChains} evmChains - The configurations for EVM chains.
* @property {string} brandURL - The URL for the brand link in the navbar.
* @property {string} bridgeURL - The URL for the bridge link in the navbar.
* @property {string} swapURL - The URL for the swap link in the navbar.
* @property {string} poolURL - The URL for the pool link in the navbar.
* @property {function} getEvmChainById - Retrieves the EVM chain with the given chain ID from the config context.
*/
export type AppConfig = {
ibcChains: IbcChains;
evmChains: EvmChains;
brandURL: string;
bridgeURL: string;
swapURL: string;
poolURL: string;
getEvmChainById(chainIdHex: string): EvmChainInfo;
};

export {
ConfigContextProvider,
type EvmChainInfo,
type EvmChains,
type EvmCurrency,
evmCurrencyBelongsToChain,
getEnvVariable,
type IbcChainInfo,
type IbcChains,
type IbcCurrency,
ibcCurrencyBelongsToChain,
toChainInfo,
useConfig,
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from "react";

import { useEthWallet } from "../../hooks/useEthWallet";
import { getEvmChains } from "config/chainConfigs";
import { useConfig } from "config";

import { useEthWallet } from "features/EthWallet/hooks/useEthWallet";

/**
* A card component for connecting to an ethereum wallet
Expand All @@ -10,7 +11,7 @@ export default function EthWalletConnector() {
const { providers, selectedWallet, userAccount, handleConnect } =
useEthWallet();

const evmChains = getEvmChains();
const { evmChains } = useConfig();
const firstKey = Object.keys(evmChains)[0];
const defaultChain = evmChains[firstKey];

Expand Down
Loading

0 comments on commit 4b755a7

Please sign in to comment.