From f7392c329edcd78846362508ea3e9c0c303c32c1 Mon Sep 17 00:00:00 2001
From: Justin <328965+justinbarry@users.noreply.github.com>
Date: Tue, 9 Jul 2024 12:20:32 -0700
Subject: [PATCH] Add account migration feature to Abstraxion dashboard
This commit introduces a new feature to the Abstraxion dashboard allowing users to migrate their accounts when needed. The `AbstraxionMigrate` component was created to handle the migration process. Also, this introduces corresponding conditions in `AbstraxionContext` and `useAbstraxionSigningClient.ts` files. Furthermore, logic added to `Abstraxion` component to continue to next step post migration.
---
apps/abstraxion-dashboard/app/page.tsx | 9 ++-
.../components/Abstraxion/index.tsx | 30 +++++--
.../components/AbstraxionContext/index.tsx | 20 ++++-
.../components/AbstraxionMigrate/index.tsx | 81 +++++++++++++++++++
.../hooks/useAbstraxionSigningClient.ts | 9 +--
5 files changed, 132 insertions(+), 17 deletions(-)
create mode 100644 apps/abstraxion-dashboard/components/AbstraxionMigrate/index.tsx
diff --git a/apps/abstraxion-dashboard/app/page.tsx b/apps/abstraxion-dashboard/app/page.tsx
index 53adba9f..32c201a5 100644
--- a/apps/abstraxion-dashboard/app/page.tsx
+++ b/apps/abstraxion-dashboard/app/page.tsx
@@ -12,19 +12,22 @@ import type { AbstraxionAccount } from "@/types";
export default function Home() {
const searchParams = useSearchParams();
- const { data: account } = useAbstraxionAccount();
+ const { isConnected, data: account } = useAbstraxionAccount();
const contracts = searchParams.get("contracts");
const stake = Boolean(searchParams.get("stake"));
const bank = searchParams.get("bank");
const grantee = searchParams.get("grantee");
- const { isOpen, setIsOpen, isMainnet } = useContext(AbstraxionContext);
+ const { isOpen, setIsOpen, isMainnet, accountNeedsToMigrate } =
+ useContext(AbstraxionContext);
const [showMobileSiderbar, setShowMobileSiderbar] = useState(false);
return (
<>
- {!account?.id || (grantee && (contracts || stake || bank)) ? (
+ {!account?.id ||
+ (grantee && (contracts || stake || bank)) ||
+ accountNeedsToMigrate ? (
diff --git a/apps/abstraxion-dashboard/components/Abstraxion/index.tsx b/apps/abstraxion-dashboard/components/Abstraxion/index.tsx
index 3fe4a26d..d06011e3 100644
--- a/apps/abstraxion-dashboard/components/Abstraxion/index.tsx
+++ b/apps/abstraxion-dashboard/components/Abstraxion/index.tsx
@@ -10,12 +10,13 @@ import {
import { apolloClient, stytchClient } from "@/lib";
import { Dialog, DialogContent } from "@burnt-labs/ui";
import { AbstraxionSignin } from "@/components/AbstraxionSignin";
-import { useAbstraxionAccount } from "@/hooks";
+import { useAbstraxionAccount, useAbstraxionSigningClient } from "@/hooks";
import { AbstraxionWallets } from "@/components/AbstraxionWallets";
import { ErrorDisplay } from "@/components/ErrorDisplay";
import { useSearchParams } from "next/navigation";
import { AbstraxionGrant } from "../AbstraxionGrant";
import Image from "next/image";
+import { AbstraxionMigrate } from "@/components/AbstraxionMigrate";
export interface ModalProps {
onClose: VoidFunction;
@@ -25,11 +26,15 @@ export interface ModalProps {
export const Abstraxion = ({ isOpen, onClose }: ModalProps) => {
const searchParams = useSearchParams();
- const { abstraxionError, isMainnet } = useContext(
- AbstraxionContext,
- ) as AbstraxionContextProps;
+ const {
+ abstraxionError,
+ isMainnet,
+ setAccountNeedsToMigrate,
+ accountNeedsToMigrate,
+ } = useContext(AbstraxionContext) as AbstraxionContextProps;
const { isConnected, data: account } = useAbstraxionAccount();
+ const { client } = useAbstraxionSigningClient();
const contracts = searchParams.get("contracts");
const stake = Boolean(searchParams.get("stake"));
@@ -60,6 +65,17 @@ export const Abstraxion = ({ isOpen, onClose }: ModalProps) => {
};
}, [onClose]);
+ async function getMetaAccountCodeID() {
+ if (client) {
+ const { codeId } = await client.getContract(account.id);
+ setAccountNeedsToMigrate(codeId === 21);
+ }
+ }
+
+ useEffect(() => {
+ if (account && client) getMetaAccountCodeID();
+ }, [account, isConnected, client]);
+
if (!isOpen) return null;
return (
@@ -79,7 +95,11 @@ export const Abstraxion = ({ isOpen, onClose }: ModalProps) => {
stake={stake}
/>
) : isConnected ? (
-
+ accountNeedsToMigrate ? (
+
+ ) : (
+
+ )
) : (
)}
diff --git a/apps/abstraxion-dashboard/components/AbstraxionContext/index.tsx b/apps/abstraxion-dashboard/components/AbstraxionContext/index.tsx
index 65ae5fa9..175671a2 100644
--- a/apps/abstraxion-dashboard/components/AbstraxionContext/index.tsx
+++ b/apps/abstraxion-dashboard/components/AbstraxionContext/index.tsx
@@ -1,4 +1,4 @@
-import { ReactNode, createContext, useState } from "react";
+import { createContext, ReactNode, useState } from "react";
import { getEnvStringOrThrow } from "@/utils";
import { ChainInfo } from "@burnt-labs/constants";
@@ -16,6 +16,8 @@ export interface AbstraxionContextProps {
isMainnet: boolean;
isOpen: boolean;
setIsOpen: React.Dispatch>;
+ setAccountNeedsToMigrate: React.Dispatch>;
+ accountNeedsToMigrate: boolean;
}
export const AbstraxionContext = createContext(
@@ -34,15 +36,26 @@ export const AbstraxionContextProvider = ({
const [abstraxionError, setAbstraxionError] = useState("");
const [isOpen, setIsOpen] = useState(false);
+ const [accountNeedsToMigrate, setAccountNeedsToMigrate] = useState(false);
+
const serializedChainInfo = getEnvStringOrThrow(
"NEXT_PUBLIC_DEFAULT_CHAIN_INFO",
process.env.NEXT_PUBLIC_DEFAULT_CHAIN_INFO,
);
const chainInfo = JSON.parse(serializedChainInfo);
- const apiUrl = getEnvStringOrThrow(
+
+ const oldApiUrl = getEnvStringOrThrow(
"NEXT_PUBLIC_DEFAULT_API_URL",
process.env.NEXT_PUBLIC_DEFAULT_API_URL,
);
+
+ const migratedApiUrl = getEnvStringOrThrow(
+ "NEXT_PUBLIC_MIGRATED_API_URL",
+ process.env.NEXT_PUBLIC_MIGRATED_API_URL,
+ );
+
+ const apiUrl = accountNeedsToMigrate ? oldApiUrl : migratedApiUrl;
+
const isMainnet =
getEnvStringOrThrow(
"NEXT_PUBLIC_DEPLOYMENT_ENV",
@@ -50,10 +63,11 @@ export const AbstraxionContextProvider = ({
) === "mainnet"
? true
: false;
-
return (
Promise;
+};
+
+export const AbstraxionMigrate = ({
+ updateContractCodeID,
+}: AbstraxionMigrateProps) => {
+ const { setAbstraxionError } = useContext(
+ AbstraxionContext,
+ ) as AbstraxionContextProps;
+
+ const { client } = useAbstraxionSigningClient();
+ const { data: account } = useAbstraxionAccount();
+ const [inProgress, setInProgress] = useState(false);
+ const [failed, setFailed] = useState(false);
+
+ const migrateAccount = async () => {
+ if (!client) return;
+ try {
+ setInProgress(true);
+
+ await client.migrate(
+ account.id,
+ account.id,
+ 793,
+ {},
+ {
+ amount: [{ amount: "0", denom: "uxion" }],
+ gas: "500000",
+ },
+ );
+
+ void updateContractCodeID();
+ } catch (error) {
+ console.log("something went wrong: ", error);
+ setFailed(true);
+ } finally {
+ setInProgress(false);
+ }
+ };
+
+ if (failed) {
+ setAbstraxionError("Failed to migrate account.");
+ return null;
+ }
+
+ if (inProgress) {
+ return (
+
+
+
+ );
+ }
+
+ return (
+
+
+
+ Congratulations!
+
+
+ Your account is due for an upgrade! Please click below to begin the
+ process.
+
+
+
+
+
+
+ );
+};
diff --git a/apps/abstraxion-dashboard/hooks/useAbstraxionSigningClient.ts b/apps/abstraxion-dashboard/hooks/useAbstraxionSigningClient.ts
index 31f78bfd..6c6b4c22 100644
--- a/apps/abstraxion-dashboard/hooks/useAbstraxionSigningClient.ts
+++ b/apps/abstraxion-dashboard/hooks/useAbstraxionSigningClient.ts
@@ -3,6 +3,7 @@ import { useStytch } from "@stytch/nextjs";
import {
AAClient,
AADirectSigner,
+ AAEthSigner,
AbstractAccountJWTSigner,
GasPrice,
} from "@burnt-labs/signers";
@@ -12,11 +13,10 @@ import {
} from "@/components/AbstraxionContext";
import { getKeplr, useOfflineSigners } from "graz";
import { testnetChainInfo } from "@burnt-labs/constants";
-import { AAEthSigner } from "@burnt-labs/signers";
import { getEnvStringOrThrow } from "@/utils";
export const useAbstraxionSigningClient = () => {
- const { connectionType, abstractAccount, chainInfo } = useContext(
+ const { connectionType, abstractAccount, chainInfo, apiUrl } = useContext(
AbstraxionContext,
) as AbstraxionContextProps;
@@ -71,10 +71,7 @@ export const useAbstraxionSigningClient = () => {
"NEXT_PUBLIC_DEFAULT_INDEXER_URL",
process.env.NEXT_PUBLIC_DEFAULT_INDEXER_URL,
),
- getEnvStringOrThrow(
- "NEXT_PUBLIC_DEFAULT_API_URL",
- process.env.NEXT_PUBLIC_DEFAULT_API_URL,
- ),
+ apiUrl,
);
break;
case "graz":