Skip to content

Commit

Permalink
fix tx handle on collapsed sidebar block
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-nax committed Sep 24, 2024
1 parent 4be5d85 commit 305feaf
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 67 deletions.
2 changes: 1 addition & 1 deletion spaceward/src/components/ui/popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const PopoverContent = React.forwardRef<
React.ElementRef<typeof PopoverPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
<PopoverPrimitive.Portal>
<PopoverPrimitive.Portal forceMount={props.forceMount}>
<PopoverPrimitive.Content
ref={ref}
align={align}
Expand Down
6 changes: 5 additions & 1 deletion spaceward/src/config/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,11 @@ export const COSMOS_PRICES: Record<string, bigint | undefined> = {
OSMO: BigInt(0.4446 * 10 ** 8),
};

const _ENABLED_ETH_CHAINS: { chainName: ChainName; testnet?: boolean }[] = [
const _ENABLED_ETH_CHAINS: {
chainName: ChainName;
testnet?: boolean;
title?: string;
}[] = [
{ chainName: "arbitrum" },
{ chainName: "astar" },
{ chainName: "avalanche" },
Expand Down
25 changes: 18 additions & 7 deletions spaceward/src/features/actions/StatusSidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import clsx from "clsx";
import { useContext, useEffect } from "react";
import { useContext, useEffect, useRef, useState } from "react";
import { isDeliverTxSuccess } from "@cosmjs/stargate";
import { useChain, walletContext } from "@cosmos-kit/react-lite";
import { cosmos, warden } from "@wardenprotocol/wardenjs";
Expand All @@ -20,7 +20,9 @@ import { QueuedAction, QueuedActionStatus, useActionsState } from "./hooks";
import { getActionHandler, GetStatus, handleCosmos, handleEth, handleEthRaw } from "./util";
import { TEMP_KEY, useKeySettingsState } from "../keys/state";
import Assets from "../keys/assets";
import { useQueryClient } from "@tanstack/react-query";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { capitalize } from "../modals/util";
import { queryCosmosClients } from "../assets/queries";

interface ItemProps extends QueuedAction {
single?: boolean;
Expand All @@ -46,6 +48,10 @@ const waitForVisibility = () => {
function ActionItem({ single, ...item }: ItemProps) {
const queryClient = useQueryClient();
const { walletManager } = useContext(walletContext);
const cosmosClients = useQuery(queryCosmosClients(walletManager)).data;
const clientsRef = useRef(cosmosClients);
clientsRef.current = cosmosClients;

const { data: ks, setData: setKeySettings } = useKeySettingsState();
const { toast } = useToast()
const { w } = useWeb3Wallet("wss://relay.walletconnect.org");
Expand Down Expand Up @@ -311,7 +317,8 @@ function ActionItem({ single, ...item }: ItemProps) {
} else if (item.networkType === "eth") {
res = await handleEth({ action: item, w, queryClient });
} else if (item.networkType === "cosmos") {
res = await handleCosmos({ action: item, w, walletManager, queryClient });
const [, , rpcEndpoint] = clientsRef.current?.find((v) => v[1] === item?.chainName) ?? [];
res = await handleCosmos({ action: item, w, queryClient, rpcEndpoint });
}
} catch (e) {
console.error("broadcast failed", e);
Expand Down Expand Up @@ -407,7 +414,7 @@ function ActionItem({ single, ...item }: ItemProps) {
? "Action ready"
: item.status ===
QueuedActionStatus.AwaitingBroadcast
? "Awaiting broadcast"
? `Awaiting broadcast on ${capitalize(item.chainName)}`
: item.status === QueuedActionStatus.Success
? "Success"
: item.status ===
Expand Down Expand Up @@ -437,6 +444,7 @@ function ActionItem({ single, ...item }: ItemProps) {
}

export default function StatusSidebar() {
const [hide, setHide] = useState(true);
const { data } = useActionsState();
const storeIds = Object.keys(data ?? {});

Expand Down Expand Up @@ -469,7 +477,9 @@ export default function StatusSidebar() {
<ActionItem single {...data?.[filtered[0]]!} />
) : null
) : (
<Popover>
<Popover onOpenChange={open => {
setHide(!open);
}}>
<PopoverTrigger asChild>
<div className="flex flex-col relative cursor-pointer">
<p className="text-lg font-semibold">
Expand All @@ -484,9 +494,10 @@ export default function StatusSidebar() {
<PopoverContent
side="left"
sideOffset={20}
className="p-0"
className={clsx("p-0", { hidden: hide })}
forceMount={hide ? true : undefined}
>
<div className="bg-fill-quaternary max-h-80 overflow-auto">
<div className={"bg-fill-quaternary max-h-80 overflow-auto"}>
{filtered.map((id) => {
const action = data?.[id];

Expand Down
1 change: 1 addition & 0 deletions spaceward/src/features/actions/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export enum QueuedActionStatus {
Broadcast,
AwaitingApprovals,
ActionReady,
// fixme rename
AwaitingBroadcast,
Success = 0x99,
Failed = 0xff,
Expand Down
21 changes: 5 additions & 16 deletions spaceward/src/features/actions/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,12 +293,12 @@ export const handleEth = async ({
export const handleCosmos = async ({
action,
w,
walletManager,
queryClient,
rpcEndpoint,
}: {
action: QueuedAction;
w: IWeb3Wallet | null;
walletManager: WalletManager;
rpcEndpoint?: string;
queryClient: QueryClient;
}) => {
const {
Expand Down Expand Up @@ -384,22 +384,11 @@ export const handleCosmos = async ({
signatures: [sig],
});

let rpc: string;
if (chain.rpc) {
[rpc] = chain.rpc;
} else {
const repo = walletManager.getWalletRepo(chainName);
repo.activate();
const endpoint = await repo.getRpcEndpoint();

rpc = endpoint
? typeof endpoint === "string"
? endpoint
: endpoint.url
: "https://rpc.cosmos.directory/" + chainName;
if (!rpcEndpoint) {
throw new Error("missing rpcEndpoint");
}

const client = await StargateClient.connect(rpc);
const client = await StargateClient.connect(rpcEndpoint);

const res = await client.broadcastTx(
cosmos.tx.v1beta1.TxRaw.encode(txRaw).finish(),
Expand Down
29 changes: 17 additions & 12 deletions spaceward/src/features/assets/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ const eip155NativeBalanceQuery = ({
throw new Error("Address is required");
}

const { provider, token } = getProvider(chainName);
const { provider, tokenSymbol: token } = getProvider(chainName);
const slinkyPrice = prices?.[token];
const priceFeed = EIP_155_NATIVE_PRICE_FEEDS[chainName];

Expand Down Expand Up @@ -427,7 +427,7 @@ const DEFAULT_BECH32_PREFIX = getCosmosChain("osmosis")!.bech32_prefix;
export const balancesQueryCosmos = (
enabled: boolean,
keys?: QueryKeyResponse[],
clients?: [CosmosQueryClient, string][],
clients?: [CosmosQueryClient, string, string][],
prices?: PriceMapSlinky,
) => {
const byAddress: Record<string, QueryKeyResponse> = {};
Expand Down Expand Up @@ -629,7 +629,10 @@ export const fiatPricesQuery = (enabled: boolean) => {
};
};

const rpcClients: Record<string, CosmosQueryClient | undefined> = {};
const rpcClients: Record<
string,
{ client: CosmosQueryClient; rpcEndpoint: string } | undefined
> = {};
const rpcRetry: Record<string, number> = {};

const checkHealth = async (
Expand Down Expand Up @@ -666,18 +669,18 @@ export const queryCosmosClients = (walletManager: WalletManager) => {
return {
queryKey: ["cosmos", "rpcClients"],
queryFn: async () => {
const clients: [CosmosQueryClient, string][] = [];
const clients: [CosmosQueryClient, string, string][] = [];

for (let i = 0; i < COSMOS_CHAINS.length; i++) {
const { chainName, rpc } = COSMOS_CHAINS[i];
const retries = (rpc?.length ?? 0) + 1;

for (let i = 0; i < retries; i++) {
let client = rpcClients[chainName];
let { client, rpcEndpoint } = rpcClients[chainName] ?? {};
const retry = (rpcRetry[chainName] ?? 0) % (retries + 1);
rpcRetry[chainName] = retry + 1;

if (!client) {
if (!client || !rpcEndpoint) {
let endpoint: ExtendedHttpEndpoint | string;

if (!rpc?.[retry]) {
Expand All @@ -694,14 +697,16 @@ export const queryCosmosClients = (walletManager: WalletManager) => {
endpoint = rpc[retry];
}

rpcEndpoint =
typeof endpoint === "string"
? endpoint
: endpoint.url;

try {
client =
await cosmos.ClientFactory.createRPCQueryClient(
{
rpcEndpoint:
typeof endpoint === "string"
? endpoint
: endpoint.url,
rpcEndpoint,
},
);
} catch (e) {
Expand All @@ -711,8 +716,8 @@ export const queryCosmosClients = (walletManager: WalletManager) => {
}

if (await checkHealth(client, chainName)) {
rpcClients[chainName] = client;
clients.push([client!, chainName]);
rpcClients[chainName] = { client, rpcEndpoint };
clients.push([client, chainName, rpcEndpoint]);
break;
} else if (rpcClients[chainName]) {
delete rpcClients[chainName];
Expand Down
17 changes: 7 additions & 10 deletions spaceward/src/features/modals/SendAssets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import { validateAddress } from "../intents/AddAddressModal";
import { StargateClient } from "@cosmjs/stargate";
import { useModalState } from "./state";
import KeySelector from "./KeySelector";
import { COSMOS_CHAINS } from "@/config/tokens";
import { walletContext } from "@cosmos-kit/react-lite";
import { BalanceEntry } from "../assets/types";
import { useQuery } from "@tanstack/react-query";
import { queryCosmosClients } from "../assets/queries";

export default function SendAssetsModal({
// address,
Expand All @@ -31,6 +32,7 @@ export default function SendAssetsModal({

const { spaceId } = useSpaceId();
const { queryBalances } = useAssetQueries(spaceId);
const cosmosClients = useQuery(queryCosmosClients(walletManager)).data;

const results: (BalanceEntry & { refetch: () => void })[] = queryBalances
.filter((result) => result.data?.key?.key?.id === key?.key?.id)
Expand Down Expand Up @@ -97,17 +99,12 @@ export default function SendAssetsModal({
setModal({ type: undefined });
}
} else if (txBuild.type === "cosmos") {
const chain = COSMOS_CHAINS.find(
(item) => item.chainName === chainName,
);

let rpc = chain?.rpc?.[0];
const [, , rpc] = cosmosClients?.find((item) => {
return item[1] === chainName
}) ?? [];

if (!rpc) {
const repo = walletManager.getWalletRepo(chainName);
repo.activate();
const endpoint = await repo.getRpcEndpoint();
rpc = endpoint ? typeof endpoint === "string" ? endpoint : endpoint.url : `https://rpc.cosmos.directory/${chainName}`;
throw new Error(`unable to find rpc for ${chainName}`);
}

const client = await StargateClient.connect(rpc);
Expand Down
17 changes: 7 additions & 10 deletions spaceward/src/hooks/state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,7 @@ export function createPersistantState<T>(
});

const ref = useRef(data);

useEffect(() => {
ref.current = data;
}, [data]);
ref.current = data;

const setData = useCallback(
(nextData: Partial<T>) => {
Expand All @@ -120,14 +117,14 @@ export function createPersistantState<T>(
JSON.stringify(_data, (_, v) =>
typeof v === "bigint"
? {
type: "bigint",
value: v.toString(),
}
type: "bigint",
value: v.toString(),
}
: v instanceof Uint8Array
? {
type: "Uint8Array",
value: Array.from(v)
}
type: "Uint8Array",
value: Array.from(v)
}
: v,
),
);
Expand Down
23 changes: 15 additions & 8 deletions spaceward/src/lib/eth/constants.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
// taken from https://chainlist.org
export const ETH_CHAIN_CONFIG: Record<
string,
{ rpc: string[]; token?: string }
{ rpc: string[]; token?: { symbol: string; name: string }; title?: string }
> = {
"1": { rpc: ["https://cloudflare-eth.com", "https://eth.llamarpc.com"] },
"1": {
rpc: ["https://cloudflare-eth.com", "https://eth.llamarpc.com"],
title: "Ethereum",
},
"5": { rpc: ["https://rpc.goerli.mudit.blog/"] },
"10": {
rpc: ["https://mainnet.optimism.io/", "https://optimism.llamarpc.com"],
Expand All @@ -13,30 +16,34 @@ export const ETH_CHAIN_CONFIG: Record<
"https://bsc-dataseed1.bnbchain.org",
"https://binance.llamarpc.com",
],
token: "BNB",
token: { symbol: "BNB", name: "Binance Coin" },
},
"61": {
rpc: ["https://etc.etcdesktop.com", "https://geth-at.etc-network.info"],
token: "ETC",
token: { symbol: "ETC", name: "Ethereum Classic" },
title: "Ethereum Classic",
},
"137": {
rpc: ["https://polygon-rpc.com/", "https://polygon.llamarpc.com"],
token: "MATIC",
token: { symbol: "MATIC", name: "Polygon" },
},
"324": { rpc: ["https://mainnet.era.zksync.io/"] },
"420": { rpc: ["https://goerli.optimism.io"] },
"592": {
rpc: ["https://astar-rpc.dwellir.com", "https://1rpc.io/astr"],
token: "ASTR",
token: { symbol: "ASTR", name: "Astar" },
},
"8453": {
rpc: ["https://mainnet.base.org/", "https://base.llamarpc.com"],
token: { symbol: "BASE", name: "Base" },
},
"8453": { rpc: ["https://mainnet.base.org/", "https://base.llamarpc.com"] },
"42161": {
rpc: ["https://arb1.arbitrum.io/rpc", "https://arbitrum.llamarpc.com"],
},
"42220": { rpc: ["https://forno.celo.org"] },
"43114": {
rpc: ["https://api.avax.network/ext/bc/C/rpc"],
token: "AVAX",
token: { symbol: "AVAX", name: "Avalanche" },
},
"44787": { rpc: ["https://alfajores-forno.celo-testnet.org"] },
"80001": { rpc: ["https://rpc-mumbai.maticvigil.com"] },
Expand Down
7 changes: 5 additions & 2 deletions spaceward/src/lib/eth/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ethers } from "ethers";
import { ETH_CHAINID_MAP, ETH_CHAIN_CONFIG } from "./constants";
import { capitalize } from "@/features/modals/util";

export const REVERSE_ETH_CHAINID_MAP = Object.fromEntries(
Object.entries(ETH_CHAINID_MAP).map(([k, v]) => [v, k]),
Expand All @@ -16,7 +17,9 @@ export const isSupportedNetwork = (
export const getProvider = (type: SupportedNetwork) => {
const chainId = ETH_CHAINID_MAP[type];
const config = ETH_CHAIN_CONFIG[chainId];
const token = config?.token ?? "ETH";
const tokenSymbol = config?.token?.symbol ?? "ETH";
const tokenName = config?.token?.name ?? "Ethereum";
const title = config?.title ?? capitalize(type);

if (!providers[type]) {
if (!chainId || !config) {
Expand Down Expand Up @@ -53,7 +56,7 @@ export const getProvider = (type: SupportedNetwork) => {
}

const provider = providers[type];
return { provider, token };
return { provider, tokenSymbol, tokenName, title };
};

export const getProviderByChainId = (chainId: string) => {
Expand Down

0 comments on commit 305feaf

Please sign in to comment.