Skip to content

Commit

Permalink
feature: use cosmjs (#14)
Browse files Browse the repository at this point in the history
* refactor getbalance

* make getBalance generic

* add envar back. lints. ibc service cleanup

* refactor ibc transfer logic. add ibc channel to envar.

* refactor justfiles.

* better command name
  • Loading branch information
steezeburger authored Aug 30, 2024
1 parent 2001ff6 commit 8d45ca0
Show file tree
Hide file tree
Showing 17 changed files with 199 additions and 184 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@ web/build

# gcloud
gsa-key.json

# ai digest
codebase.md
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ the Astria bridge.

```bash
# install npm deps and run web app locally
just install-web-deps
just generate-initial-web-env
just run-web-local
just web init-env
just web install
just web run

# build web app static files
just build-web
just web build
```
29 changes: 4 additions & 25 deletions justfile
Original file line number Diff line number Diff line change
@@ -1,29 +1,8 @@
import 'justfile.codestyle'
import 'justfile.utils'
import 'justfile.tests'

default:
@just --list

# Project Setup

# copies web/.env.example to web/.env
generate-initial-web-env:
cp web/.env.example web/.env

# installs npm deps for web
install-web-deps:
cd web && npm install
mod web

# builds the typescript for the front end app
build-web:
cd web && npm run build

# deploys a temporarily accessible preview of the site
deploy-hosting-preview:
GOOGLE_APPLICATION_CREDENTIALS=./web/src/gsa-key.json \
firebase hosting:channel:deploy astriatest

# run front end app locally,
# with file watching that triggers rebuilds
run-web-local:
cd web && npm run start
_default:
@just --list
9 changes: 7 additions & 2 deletions justfile.codestyle
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@
default_lang := 'all'

# Can lint 'ts', 'md', or 'all'. Defaults to all
[group('lint')]
[group('codestyle')]
lint lang=default_lang:
@just _lint-{{lang}}

# lint and fix issues that can be fixed. pass "unsafe" to also apply unsafe fixes.
[group('codestyle')]
lint-ts-apply unsafe='':
cd web; npm run lint-apply{{ if unsafe == "unsafe" { "-unsafe" } else { "" } }}

alias l := lint

@_lint-all:
Expand All @@ -26,7 +31,7 @@ _lint-ts:
cd web; npm run lint

# Can format 'ts', 'md', or 'all'. Defaults to all
[group('format')]
[group('codestyle')]
fmt lang=default_lang:
@just _fmt-{{lang}}

Expand Down
21 changes: 21 additions & 0 deletions justfile.utils
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
defaultUrl := 'http://rest.app.celestia.localdev.me'
defaultAddress := 'celestia1m0ksdjl2p5nzhqy3p47fksv52at3ln885xvl96'
[group('utils')]
@celestia-get-balances url=defaultUrl address=defaultAddress:
#!/bin/sh
curl '{{ url }}/cosmos/bank/v1beta1/balances/{{ address }}?pagination.limit=1000' \
-H 'accept: */*' \
-H 'accept-language: en-US,en;q=0.9' \
-H 'origin: http://localhost:3000' \
-H 'priority: u=1, i' \
-H 'referer: http://localhost:3000/'

[group('utils')]
@celestia-get-txs url=defaultUrl address=defaultAddress:
#!/bin/sh
curl "{{ url }}/cosmos/tx/v1beta1/txs?events=message.sender='{{ address }}'&pagination.limit=1000" \
-H 'accept: */*' \
-H 'accept-language: en-US,en;q=0.9' \
-H 'origin: http://localhost:3000' \
-H 'priority: u=1, i' \
-H 'referer: http://localhost:3000/'
1 change: 1 addition & 0 deletions web/.aidigestignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public/fonts
2 changes: 2 additions & 0 deletions web/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ REACT_APP_CELESTIA_FEE_CURRENCIES_COIN_DECIMALS=6
REACT_APP_CELESTIA_FEE_CURRENCIES_GAS_PRICE_STEP_LOW=0.01
REACT_APP_CELESTIA_FEE_CURRENCIES_GAS_PRICE_STEP_AVERAGE=0.02
REACT_APP_CELESTIA_FEE_CURRENCIES_GAS_PRICE_STEP_HIGH=0.1
REACT_APP_CELESTIA_IBC_CHANNEL="channel-110"
REACT_APP_CELESTIA_ICON_SOURCE_URL="https://placehold.co/60x60/EEE/31343C"
18 changes: 18 additions & 0 deletions web/justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
_default:
@just --list

# copies web/.env.example to web/.env
init-env:
cp .env.example .env

# installs npm deps for web
install:
npm install

# builds the typescript for the front end app
build:
npm run build

# run front end app locally, with file watching that triggers rebuilds
run:
npm run start
23 changes: 0 additions & 23 deletions web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,14 @@
import type React from "react";
import { useEffect } from "react";
import { Route, Routes } from "react-router-dom";

import { CelestiaChainInfo } from "chainInfos";
import { EthWalletContextProvider } from "features/EthWallet/contexts/EthWalletContext";
import BridgePage from "pages/BridgePage/BridgePage";
import Layout from "pages/Layout";
import { NotificationsProvider } from "providers/NotificationsProvider";
import { getKeplrFromWindow } from "services/keplr";

/**
* App component with routes.
*/
export default function App(): React.ReactElement {
useEffect(() => {
void suggestCelestia();
}, []);

const suggestCelestia = async () => {
const keplr = await getKeplrFromWindow();
if (!keplr) {
return;
}

try {
await keplr.experimentalSuggestChain(CelestiaChainInfo);
} catch (e) {
if (e instanceof Error) {
console.error(e.message);
}
}
};

return (
<NotificationsProvider>
<EthWalletContextProvider>
Expand Down
57 changes: 32 additions & 25 deletions web/src/components/DepositCard/DepositCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ import AnimatedArrowSpacer from "components/AnimatedDownArrowSpacer/AnimatedDown
import EthWalletConnector from "features/EthWallet/components/EthWalletConnector/EthWalletConnector";
import { NotificationsContext } from "contexts/NotificationsContext";
import { useEthWallet } from "features/EthWallet/hooks/useEthWallet";
import { getJSON } from "services/api";
import { sendIbcTransfer } from "services/ibc";
import { getBalance, sendIbcTransfer } from "services/ibc";
import { getKeplrFromWindow } from "services/keplr";
import type { Balances } from "types";
import { useIbcChainSelection } from "features/IbcChainSelector/hooks/useIbcChainSelection";
import Dropdown from "../Dropdown/Dropdown";
import { useIbcChainSelection } from "../../features/IbcChainSelector/IbcChainSelector";

export default function DepositCard(): React.ReactElement {
const { addNotification } = useContext(NotificationsContext);
Expand All @@ -29,6 +27,7 @@ export default function DepositCard(): React.ReactElement {
useState<boolean>(false);
const [hasTouchedForm, setHasTouchedForm] = useState<boolean>(false);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [isLoadingBalance, setIsLoadingBalance] = useState<boolean>(false);
const [isAnimating, setIsAnimating] = useState<boolean>(false);

// set recipient address if userAccount available,
Expand All @@ -48,36 +47,39 @@ export default function DepositCard(): React.ReactElement {
checkIsFormValid(recipientAddress, amount);
}, [recipientAddress, amount]);

const getBalance = async () => {
const getAndSetBalance = async () => {
if (!selectedIbcChain) {
return;
}
const key = await window.keplr?.getKey(selectedIbcChain.chainId);

if (key) {
const uri = `${selectedIbcChain.rest}/cosmos/bank/v1beta1/balances/${key.bech32Address}?pagination.limit=1000`;

const data = await getJSON<Balances>(uri);
const balance = data.balances.find((balance) => balance.denom === "utia");
const tiaDecimal = selectedIbcChain.currencies.find(
(currency: { coinMinimalDenom: string }) =>
currency.coinMinimalDenom === "utia",
)?.coinDecimals;

if (balance) {
const amount = new Dec(balance.amount, tiaDecimal);
setBalance(`${amount.toString(tiaDecimal)} TIA`);
} else {
setBalance("0 TIA");
}
try {
setIsLoadingBalance(true);
const balance = await getBalance(selectedIbcChain);
setBalance(balance);
} catch (e) {
console.error(e);
setBalance("Error fetching balance");
} finally {
setIsLoadingBalance(false);
}
};

const sendBalance = async () => {
if (!selectedIbcChain) {
addNotification({
toastOpts: {
toastType: NotificationType.WARNING,
message: "Please select a chain first.",
onAcknowledge: () => {},
},
});
return;
}

setIsLoading(true);
setIsAnimating(true);
try {
await sendIbcTransfer(
selectedIbcChain,
fromAddress,
recipientAddress,
DecUtils.getTenExponentN(6).mul(new Dec(amount)).truncate().toString(),
Expand Down Expand Up @@ -137,7 +139,7 @@ export default function DepositCard(): React.ReactElement {
try {
const key = await keplr.getKey(selectedIbcChain.chainId);
setFromAddress(key.bech32Address);
await getBalance();
await getAndSetBalance();
} catch (e) {
if (e instanceof Error) {
console.error(e.message);
Expand Down Expand Up @@ -223,9 +225,14 @@ export default function DepositCard(): React.ReactElement {
</button>
</div>
<div>
{fromAddress && (
{fromAddress && !isLoadingBalance && (
<p className="mt-2 has-text-light">Balance: {balance}</p>
)}
{fromAddress && isLoadingBalance && (
<p className="mt-2 has-text-light">
Balance: <i className="fas fa-spinner fa-pulse" />
</p>
)}
</div>
</div>
</div>
Expand Down
3 changes: 1 addition & 2 deletions web/src/components/WithdrawCard/WithdrawCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { NotificationsContext } from "contexts/NotificationsContext";
import AnimatedArrowSpacer from "components/AnimatedDownArrowSpacer/AnimatedDownArrowSpacer";
import { NotificationType } from "components/Notification/types";
import { getKeplrFromWindow } from "services/keplr";
import { CelestiaChainInfo } from "chainInfos";
import {
EthWalletConnector,
getAstriaWithdrawerService,
Expand Down Expand Up @@ -96,7 +95,7 @@ export default function WithdrawCard(): React.ReactElement {
}

try {
const key = await keplr.getKey(CelestiaChainInfo.chainId);
const key = await keplr.getKey(selectedIbcChain.chainId);
setToAddress(key.bech32Address);
} catch (e) {
if (e instanceof Error) {
Expand Down
Empty file.
32 changes: 15 additions & 17 deletions web/src/config/chains.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
import type { ChainInfo } from "@keplr-wallet/types";
import { capitalize, getEnvVariable } from "../utils";
import { capitalize, getEnvVariable } from "utils";

// IbcChains maps labels to ChainInfo objects
export type IbcChainInfo = {
ibcChannel: string;
iconSourceUrl: string;
} & ChainInfo;

// IbcChains maps labels to IbcChainInfo objects
export type IbcChains = {
[label: string]: ChainInfo;
[label: string]: IbcChainInfo;
};

// type EvmChainInfo = {
// chainId: string;
// rpc: string;
// rest: string;
// withdrawerContractAddress: string;
//
// };
//
// export type EvmChains = {
// // TODO
// [key: string]: {};
// };

export function generateChainInfo(envVars: {
CHAIN_ID: string;
CHAIN_NAME: string;
Expand All @@ -38,12 +30,16 @@ export function generateChainInfo(envVars: {
FEE_CURRENCIES_GAS_PRICE_STEP_LOW: string;
FEE_CURRENCIES_GAS_PRICE_STEP_AVERAGE: string;
FEE_CURRENCIES_GAS_PRICE_STEP_HIGH: string;
}): ChainInfo {
IBC_CHANNEL: string;
ICON_SOURCE_URL: string;
}): IbcChainInfo {
return {
chainId: envVars.CHAIN_ID,
chainName: envVars.CHAIN_NAME,
rpc: envVars.RPC_ENDPOINT,
rest: envVars.REST_ENDPOINT,
ibcChannel: envVars.IBC_CHANNEL,
iconSourceUrl: envVars.ICON_SOURCE_URL,
stakeCurrency: {
coinDenom: envVars.STAKE_CURRENCY_COIN_DENOM,
coinMinimalDenom: envVars.STAKE_CURRENCY_COIN_MINIMAL_DENOM,
Expand Down Expand Up @@ -95,6 +91,8 @@ export function parseMultiChainEnvVars(): IbcChains {
CHAIN_NAME: getEnvVariable(`${prefix}_CHAIN_NAME`),
RPC_ENDPOINT: getEnvVariable(`${prefix}_RPC_ENDPOINT`),
REST_ENDPOINT: getEnvVariable(`${prefix}_REST_ENDPOINT`),
IBC_CHANNEL: getEnvVariable(`${prefix}_IBC_CHANNEL`),
ICON_SOURCE_URL: getEnvVariable(`${prefix}_ICON_SOURCE_URL`),
STAKE_CURRENCY_COIN_DENOM: getEnvVariable(
`${prefix}_STAKE_CURRENCY_COIN_DENOM`,
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import { useState, useMemo } from "react";
import type { ChainInfo } from "@keplr-wallet/types";
import type { DropdownOption } from "components/Dropdown/Dropdown";
import { ChainConfigs } from "config/chains";
import { ChainConfigs, type IbcChainInfo } from "config/chains";

export function useIbcChainSelection() {
const [selectedIbcChain, setSelectedIbcChain] = useState<ChainInfo | null>(
const [selectedIbcChain, setSelectedIbcChain] = useState<IbcChainInfo | null>(
null,
);

const ibcChainsOptions = useMemo(() => {
return Object.entries(ChainConfigs).map(
([chainLabel, chain]): DropdownOption<ChainInfo> => ({
([chainLabel, chain]): DropdownOption<IbcChainInfo> => ({
label: chainLabel,
value: chain,
}),
);
}, []);

const selectIbcChain = (chain: ChainInfo) => {
const selectIbcChain = (chain: IbcChainInfo) => {
setSelectedIbcChain(chain);
};

Expand Down
2 changes: 1 addition & 1 deletion web/src/features/IbcChainSelector/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { useIbcChainSelection } from "./IbcChainSelector";
import { useIbcChainSelection } from "./hooks/useIbcChainSelection";

export { useIbcChainSelection };
Loading

0 comments on commit 8d45ca0

Please sign in to comment.