From 68136d1df8cb48360b08d2d39195616cc326faeb Mon Sep 17 00:00:00 2001 From: Burnt Val Date: Wed, 6 Mar 2024 16:24:16 -0500 Subject: [PATCH 01/10] refactor abstraxion to fetch config --- .../src/components/Abstraxion/index.tsx | 2 - .../components/AbstraxionContext/index.tsx | 18 ++++- .../src/components/AbstraxionSignin/index.tsx | 2 +- packages/constants/src/index.ts | 23 ++++++ packages/constants/src/types.ts | 70 +++++++++++++++++++ 5 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 packages/constants/src/types.ts diff --git a/packages/abstraxion/src/components/Abstraxion/index.tsx b/packages/abstraxion/src/components/Abstraxion/index.tsx index cf05b018..4fb2779b 100644 --- a/packages/abstraxion/src/components/Abstraxion/index.tsx +++ b/packages/abstraxion/src/components/Abstraxion/index.tsx @@ -64,7 +64,6 @@ export function Abstraxion({ onClose }: ModalProps): JSX.Element | null { export interface AbstraxionConfig { contracts?: ContractGrantDescription[]; - dashboardUrl?: string; rpcUrl?: string; restUrl?: string; stake?: boolean; @@ -81,7 +80,6 @@ export function AbstraxionProvider({ return ( ( export function AbstraxionContextProvider({ children, contracts, - dashboardUrl = "https://dashboard.burnt.com", rpcUrl = testnetChainInfo.rpc, restUrl = testnetChainInfo.rest, stake = false, @@ -63,6 +62,21 @@ export function AbstraxionContextProvider({ DirectSecp256k1HdWallet | undefined >(undefined); const [granterAddress, setGranterAddress] = useState(""); + const [dashboardUrl, setDashboardUrl] = useState(""); + + // Not loving this useEffect. Halts user action on mount because of await + useEffect(() => { + async function fetchDashboardUrl() { + try { + const url = await fetchConfig(rpcUrl); + setDashboardUrl(url); + } catch (error) { + console.warn("Error fetching config. Make sure RPC url is valid"); + } + } + + fetchDashboardUrl(); + }, []); useEffect(() => { const searchParams = new URLSearchParams(window.location.search); diff --git a/packages/abstraxion/src/components/AbstraxionSignin/index.tsx b/packages/abstraxion/src/components/AbstraxionSignin/index.tsx index 3b56ede9..715c0556 100644 --- a/packages/abstraxion/src/components/AbstraxionSignin/index.tsx +++ b/packages/abstraxion/src/components/AbstraxionSignin/index.tsx @@ -87,7 +87,7 @@ export function AbstraxionSignin(): JSX.Element { } urlParams.set("redirect_uri", currentUrl); const queryString = urlParams.toString(); // Convert URLSearchParams to string - window.location.href = `${dashboardUrl}?${queryString}`; + window.location.href = `https://${dashboardUrl}?${queryString}`; } async function generateAndStoreTempAccount(): Promise { diff --git a/packages/constants/src/index.ts b/packages/constants/src/index.ts index cee414c9..377f2ff0 100644 --- a/packages/constants/src/index.ts +++ b/packages/constants/src/index.ts @@ -1,3 +1,5 @@ +import { RpcStatusResponse } from "./types"; + export interface Coin { coinDenom: string; coinMinimalDenom: string; @@ -88,3 +90,24 @@ export const testChainInfo: ChainInfo = { chainId: "xion-local-testnet-1", chainName: "Xion Testnet Local", }; + +// TODO: Adjust to finalized deployments +const mainnetDashboardUrl = "dashboard.burnt.com"; +const testnetDashboardUrl = "testnet-dashboard.burnt.com"; + +export async function fetchConfig(rpcUrl: string): Promise { + try { + const fetchReq = await fetch(`${rpcUrl}/status`); + if (!fetchReq.ok) { + throw new Error("Something went wrong querying RPC"); + } + + const data: RpcStatusResponse = await fetchReq.json(); + // If mainnet chain-id/network changes be sure to update here. + return data.result.node_info.network === "xion-mainnet-1" + ? mainnetDashboardUrl + : testnetDashboardUrl; + } catch (error) { + throw error; + } +} diff --git a/packages/constants/src/types.ts b/packages/constants/src/types.ts new file mode 100644 index 00000000..647d427c --- /dev/null +++ b/packages/constants/src/types.ts @@ -0,0 +1,70 @@ +export interface Coin { + coinDenom: string; + coinMinimalDenom: string; + coinDecimals: number; + gasPriceStep: { + low: number; + average: number; + high: number; + }; +} + +interface Bech32Config { + bech32PrefixAccAddr: string; + bech32PrefixValAddr: string; + bech32PrefixValPub: string; + bech32PrefixAccPub: string; + bech32PrefixConsAddr: string; + bech32PrefixConsPub: string; +} + +interface Bip44 { + coinType: number; +} + +export interface ChainInfo { + rpc: string; + rest: string; + chainId: string; + stakeCurrency: Coin; + chainName: string; + bip44: Bip44; + bech32Config: Bech32Config; + currencies: Coin[]; + feeCurrencies: Coin[]; + features: string[]; +} + +// Interface for rpc status response +export interface RpcStatusResponse { + jsonrpc: string; + id: number; + result: RpcStatusResult; +} + +export interface RpcStatusResult { + node_info: RpcStatusResultNodeInfo; + sync_info: RpcStatusResultSyncInfo; +} + +export interface RpcStatusResultNodeInfo { + protocol_version: any; + id: string; + network: string; + version: string; + channels: string; + moniker: string; + other: any; +} + +export interface RpcStatusResultSyncInfo { + latest_block_hash: string; + latest_app_hash: string; + latest_block_height: string; + latest_block_time: string; + earliest_block_hash: string; + earliest_app_hash: string; + earliest_block_height: string; + earliest_block_time: string; + catching_up: boolean; +} From 12b995f5c3216bad7537d4232ea2bbd2340ced32 Mon Sep 17 00:00:00 2001 From: Burnt Val Date: Wed, 6 Mar 2024 16:26:08 -0500 Subject: [PATCH 02/10] add changeset --- .changeset/twelve-bulldogs-collect.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/twelve-bulldogs-collect.md diff --git a/.changeset/twelve-bulldogs-collect.md b/.changeset/twelve-bulldogs-collect.md new file mode 100644 index 00000000..2c4bbb8f --- /dev/null +++ b/.changeset/twelve-bulldogs-collect.md @@ -0,0 +1,6 @@ +--- +"@burnt-labs/abstraxion": minor +"@burnt-labs/constants": minor +--- + +Refactor Abstraxion to fetch config From a0526fcb0f6d1f0cabab2babe148a72625aa15fc Mon Sep 17 00:00:00 2001 From: Burnt Val Date: Wed, 6 Mar 2024 16:40:26 -0500 Subject: [PATCH 03/10] add env var step to github actions --- .github/workflows/release.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d70cb5d8..c95a7167 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -62,6 +62,11 @@ jobs: id: install-dependencies run: pnpm install + - name: Rename Env file + id: rename-env-file + run: | + mv apps/abstraxion-dashboard/.env.example apps/abstraxion-dashboard/.env + - name: 🏗️ Build id: build-the-mono-repo run: | From 536ed9461c0c54305f40a4e6a2d3bda55776c3e9 Mon Sep 17 00:00:00 2001 From: Burnt Val Date: Wed, 6 Mar 2024 16:43:45 -0500 Subject: [PATCH 04/10] add ci actions for PRs --- .github/workflows/ci.yml | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..7168fb1e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,67 @@ +name: 🚀 CI + +on: + push: + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +jobs: + release: + name: 🚀 Release + strategy: + matrix: + os: [ubuntu-latest] + node-version: [lts/*] + pnpm-version: [latest] + runs-on: ${{ matrix.os }} + steps: + - name: ⬇️ Checkout + id: checkout + uses: actions/checkout@v2.3.3 + with: + token: ${{ env.GITHUB_TOKEN }} + fetch-depth: 0 + + - name: 🟢 Setup node + id: setup-node + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + + - name: 🥡 Setup pnpm + id: setup-pnpm + uses: pnpm/action-setup@v2.4.0 + with: + version: ${{ matrix.pnpm-version }} + run_install: false + + - name: 🎈 Get pnpm store directory + id: get-pnpm-cache-dir + run: | + echo "::set-output name=pnpm_cache_dir::$(pnpm store path)" + + - name: 🔆 Cache pnpm modules + uses: actions/cache@v3 + id: pnpm-cache + with: + path: ${{ steps.get-pnpm-cache-dir.outputs.pnpm_cache_dir }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: 🧩 Install Dependencies + id: install-dependencies + run: pnpm install + + - name: Rename Env file + id: rename-env-file + run: | + mv apps/abstraxion-dashboard/.env.example apps/abstraxion-dashboard/.env + + - name: 🏗️ Build + id: build-the-mono-repo + run: | + pnpm build From 7425cec0c140210ab09fad88a95db75070257b8e Mon Sep 17 00:00:00 2001 From: Burnt Val Date: Wed, 6 Mar 2024 17:06:50 -0500 Subject: [PATCH 05/10] relocate fetchConfig; add some error handling --- .../components/AbstraxionContext/index.tsx | 20 ++++--------------- .../src/components/AbstraxionSignin/index.tsx | 18 ++++++++++++++--- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/abstraxion/src/components/AbstraxionContext/index.tsx b/packages/abstraxion/src/components/AbstraxionContext/index.tsx index 7ecd5579..46fa3e2b 100644 --- a/packages/abstraxion/src/components/AbstraxionContext/index.tsx +++ b/packages/abstraxion/src/components/AbstraxionContext/index.tsx @@ -27,8 +27,9 @@ export interface AbstraxionContextProps { setGranterAddress: React.Dispatch>; contracts?: ContractGrantDescription[]; dashboardUrl?: string; - rpcUrl?: string; - restUrl?: string; + setDashboardUrl: React.Dispatch>; + rpcUrl: string; + restUrl: string; stake?: boolean; bank?: SpendLimit[]; logout?: () => void; @@ -64,20 +65,6 @@ export function AbstraxionContextProvider({ const [granterAddress, setGranterAddress] = useState(""); const [dashboardUrl, setDashboardUrl] = useState(""); - // Not loving this useEffect. Halts user action on mount because of await - useEffect(() => { - async function fetchDashboardUrl() { - try { - const url = await fetchConfig(rpcUrl); - setDashboardUrl(url); - } catch (error) { - console.warn("Error fetching config. Make sure RPC url is valid"); - } - } - - fetchDashboardUrl(); - }, []); - useEffect(() => { const searchParams = new URLSearchParams(window.location.search); if (searchParams.get("granted") === "true") { @@ -110,6 +97,7 @@ export function AbstraxionContextProvider({ setGranterAddress, contracts, dashboardUrl, + setDashboardUrl, rpcUrl, restUrl, stake, diff --git a/packages/abstraxion/src/components/AbstraxionSignin/index.tsx b/packages/abstraxion/src/components/AbstraxionSignin/index.tsx index 715c0556..64f83cd4 100644 --- a/packages/abstraxion/src/components/AbstraxionSignin/index.tsx +++ b/packages/abstraxion/src/components/AbstraxionSignin/index.tsx @@ -7,6 +7,7 @@ import { AbstraxionContext, ContractGrantDescription, } from "../AbstraxionContext"; +import { fetchConfig } from "@burnt-labs/constants"; interface GrantsResponse { grants: Grant[]; @@ -49,11 +50,14 @@ export function AbstraxionSignin(): JSX.Element { const { setIsConnecting, setIsConnected, + setAbstraxionError, setAbstraxionAccount, setGranterAddress, granterAddress, contracts, dashboardUrl, + setDashboardUrl, + rpcUrl, restUrl, stake, bank, @@ -70,7 +74,12 @@ export function AbstraxionSignin(): JSX.Element { function openDashboardTab( userAddress: string, grantContracts?: ContractGrantDescription[], + dashUrl?: string, ): void { + if (!dashboardUrl) { + console.warn("Failed to fetch dashboard url"); + setAbstraxionError("Failed to fetch dashboard url"); + } const currentUrl = window.location.href; const urlParams = new URLSearchParams(); @@ -87,7 +96,7 @@ export function AbstraxionSignin(): JSX.Element { } urlParams.set("redirect_uri", currentUrl); const queryString = urlParams.toString(); // Convert URLSearchParams to string - window.location.href = `https://${dashboardUrl}?${queryString}`; + window.location.href = `https://${dashUrl}?${queryString}`; } async function generateAndStoreTempAccount(): Promise { @@ -158,7 +167,9 @@ export function AbstraxionSignin(): JSX.Element { setTempAccountAddress(address); if (!isGranted && !granterAddress) { - openDashboardTab(address, contracts); + const dashUrl = await fetchConfig(rpcUrl); + setDashboardUrl(dashUrl); + openDashboardTab(address, contracts, dashUrl); } else if (isGranted && !granterAddress) { await pollForGrants(address); setIsConnecting(false); @@ -169,6 +180,7 @@ export function AbstraxionSignin(): JSX.Element { } } catch (error) { console.log("Something went wrong: ", error); + setAbstraxionError((error as Error).message); } } @@ -193,7 +205,7 @@ export function AbstraxionSignin(): JSX.Element {