Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.local
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
NEXT_PUBLIC_WEB3AUTH_NETWORK=testnet
NEXT_PUBLIC_WEB3AUTH_CLIENT_ID=BKj3lr6GfN2CnvO4CIKo5fuoCg_TpHsAPK7R8lbl6kUlz0CAH_5mFNswScEb7M6szV4hd1Tkwa2oPZ9KiXJB-44
NEXT_PUBLIC_GHOSTCLOUD_RPC_TARGET=http://localhost:26657
NEXT_PUBLIC_GHOSTCLOUD_REST_TARGET=http://localhost:1317
NEXT_PUBLIC_GHOSTCLOUD_CHAIN_NAMESPACE=other
NEXT_PUBLIC_GHOSTCLOUD_DISPLAY_NAME=Ghostcloud
NEXT_PUBLIC_GHOSTCLOUD_CHAIN_ID=gc-local
Expand Down
4 changes: 2 additions & 2 deletions __tests__/components/address-display.test.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// @ts-nocheck
import "@testing-library/jest-dom"
import { render, screen } from "@testing-library/react"
import { useQuery } from "react-query"
import { useQuery } from "@tanstack/react-query"
import AddressDisplay from "../../components/address-display"

jest.mock("react-query", () => ({
jest.mock("@tanstack/react-query", () => ({
useQuery: jest.fn(),
}))
describe("AddressDisplay", () => {
Expand Down
4 changes: 2 additions & 2 deletions __tests__/components/balance-display.test.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// @ts-nocheck
import "@testing-library/jest-dom"
import { render, screen } from "@testing-library/react"
import { useQuery } from "react-query"
import { useQuery } from "@tanstack/react-query"
import BalanceDisplay from "../../components/balance-display"

jest.mock("react-query", () => ({
jest.mock("@tanstack/react-query", () => ({
useQuery: jest.fn(),
}))

Expand Down
2 changes: 1 addition & 1 deletion __tests__/components/create-deployment.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { render, screen, fireEvent, waitFor } from "@testing-library/react"
import CreateDeploymentModal from "../../components/create-deployment"

jest.mock("react-query", () => ({
jest.mock("@tanstack/react-query", () => ({
useQuery: jest.fn(),
useQueryClient: jest.fn(),
useMutation: jest.fn(),
Expand Down
10 changes: 2 additions & 8 deletions __tests__/components/dashboard.test.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
// @ts-nocheck
import { render, screen, fireEvent, waitFor } from "@testing-library/react"
import { useQuery } from "react-query"
import { render, screen, fireEvent } from "@testing-library/react"
import Dashboard from "../../components/dashboard"
import useWeb3AuthStore from "../../store/web3-auth"
import {
useCreateDeployment,
useFetchMetas,
useUpdateDeployment,
useRemoveDeployment,
} from "../../lib/ghostcloud"
import { useFetchMetas } from "../../lib/ghostcloud"

jest.mock("../../lib/ghostcloud", () => ({
useCreateDeployment: jest.fn(),
Expand Down
3 changes: 2 additions & 1 deletion components/dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { GHOSTCLOUD_INFRA_LOADBALANCER_IP } from "../config/ghostcloud-infra"
import useWeb3AuthStore from "../store/web3-auth"
import { truncateAddress } from "../helpers/address"
import { FaInfoCircle } from "react-icons/fa"
import { Meta } from "@liftedinit/gcjs/dist/codegen/ghostcloud/ghostcloud/meta"

function createUrl(name: string, address: string) {
return `${GHOSTCLOUD_URL_SCHEME}://${name}-${address}.${GHOSTCLOUD_URL_DOMAIN}`
Expand Down Expand Up @@ -132,7 +133,7 @@ const Dashboard = () => {
</Tr>
</Thead>
<Tbody>
{metas.meta.map((meta, index) => (
{metas.meta.map((meta: Meta, index: number) => (
<Tr key={index}>
<Td>{meta.name}</Td>
<Td>{meta.description}</Td>
Expand Down
3 changes: 3 additions & 0 deletions config/ghostcloud-chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export const GHOSTCLOUD_ADDRESS_PREFIX =
export const GHOSTCLOUD_RPC_TARGET =
process.env["NEXT_PUBLIC_GHOSTCLOUD_RPC_TARGET"] ??
"https://rpc.testnet.ghostcloud.org"
export const GHOSTCLOUD_REST_TARGET =
process.env["NEXT_PUBLIC_GHOSTCLOUD_REST_TARGET"] ??
"https://rest.testnet.ghostcloud.org"
export const GHOSTCLOUD_CHAIN_NAMESPACE = (process.env[
"NEXT_PUBLIC_GHOSTCLOUD_CHAIN_NAMESPACE"
] ?? "other") as ChainNamespaceType
Expand Down
15 changes: 5 additions & 10 deletions config/web3-auth.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,22 @@
import { OPENLOGIN_NETWORK_TYPE, WALLET_ADAPTERS } from "@web3auth/base"
import {
MFA_LEVELS,
OpenLoginOptions,
UX_MODE,
} from "@toruslabs/openlogin-utils"
import { LoginSettings } from "@web3auth/openlogin-adapter"
import { WEB3AUTH_NETWORK_TYPE, WALLET_ADAPTERS, UX_MODE } from "@web3auth/base"
import { AuthOptions, LoginSettings, MFA_LEVELS } from "@web3auth/auth-adapter"

export const WEB3AUTH_CLIENT_ID =
process.env["NEXT_PUBLIC_WEB3AUTH_CLIENT_ID"] ?? "invalid"
export const WEB3AUTH_NETWORK = process.env[
"NEXT_PUBLIC_WEB3AUTH_NETWORK"
] as OPENLOGIN_NETWORK_TYPE
] as WEB3AUTH_NETWORK_TYPE

export const WEB3AUTH_ADAPTER_SETTINGS = {
uxMode: UX_MODE.POPUP,
} as OpenLoginOptions
} as AuthOptions

export const WEB3AUTH_LOGIN_SETTINGS = {
mfaLevel: MFA_LEVELS.OPTIONAL,
} as LoginSettings

export const WEB3AUTH_MODAL_CONFIG = {
[WALLET_ADAPTERS.OPENLOGIN]: {
[WALLET_ADAPTERS.AUTH]: {
label: "openlogin",
loginMethods: {
facebook: {
Expand Down
21 changes: 21 additions & 0 deletions hooks/useLcdQueryClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ghostcloud } from "@liftedinit/gcjs"
import { useQuery } from "@tanstack/react-query"
import { GHOSTCLOUD_REST_TARGET } from "../config/ghostcloud-chain"

const createLcdQueryClient = ghostcloud.ClientFactory.createLCDClient

export const useLcdQueryClient = () => {
const lcdQueryClient = useQuery({
queryKey: ["lcdQueryClientCosmos", GHOSTCLOUD_REST_TARGET],
queryFn: () =>
createLcdQueryClient({
restEndpoint: GHOSTCLOUD_REST_TARGET,
}),
enabled: !!GHOSTCLOUD_REST_TARGET,
staleTime: Infinity,
})

return {
lcdQueryClient: lcdQueryClient.data,
}
}
84 changes: 40 additions & 44 deletions lib/ghostcloud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,21 @@ import {
import { DeploymentData } from "../components/create-deployment"
import { fileToArrayBuffer } from "../helpers/files"
import {
keepPreviousData,
useMutation,
useQuery,
useQueryClient,
UseQueryResult,
} from "react-query"
import { QueryMetasResponse } from "@liftedinit/gcjs/dist/codegen/ghostcloud/ghostcloud/query"
import { useDisplayError } from "../helpers/errors"
} from "@tanstack/react-query"
import { QueryMetasResponseSDKType } from "@liftedinit/gcjs/dist/codegen/ghostcloud/ghostcloud/query"
import {
AminoTypes,
calculateFee,
Coin,
SigningStargateClient,
} from "@cosmjs/stargate"
import { hexToBytes } from "@metamask/utils"
import { fromHex } from "@cosmjs/encoding"
import { useLcdQueryClient } from "../hooks/useLcdQueryClient"

async function createSigner(pk: Uint8Array) {
const getSignerFromKey = async (): Promise<OfflineDirectSigner> => {
Expand Down Expand Up @@ -116,7 +117,7 @@ export const useCreateDeployment = () => {
}

const client = await createGhostcloudRpcClient(
hexToBytes(await store.getPrivateKey()),
fromHex(await store.getPrivateKey()),
)
const msg = await createDeploymentMsg(data, creator)
const gasEstimation = await client.simulate(creator, [msg], "")
Expand All @@ -142,8 +143,8 @@ export const useCreateDeployment = () => {
return useMutation({
mutationFn: create,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: "metas" })
queryClient.invalidateQueries({ queryKey: "balance" })
queryClient.invalidateQueries({ queryKey: ["metas"] })
queryClient.invalidateQueries({ queryKey: ["userBalance"] })
},
})
}
Expand Down Expand Up @@ -186,7 +187,7 @@ export const useUpdateDeployment = () => {
}

const client = await createGhostcloudRpcClient(
hexToBytes(await store.getPrivateKey()),
fromHex(await store.getPrivateKey()),
)
const msg = await updateDeploymentMsg(data, creator)
const gasEstimation = await client.simulate(creator, [msg], "")
Expand All @@ -213,8 +214,8 @@ export const useUpdateDeployment = () => {
return useMutation({
mutationFn: update,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: "metas" })
queryClient.invalidateQueries({ queryKey: "balance" })
queryClient.invalidateQueries({ queryKey: ["metas"] })
queryClient.invalidateQueries({ queryKey: ["userBalance"] })
},
})
}
Expand All @@ -237,7 +238,7 @@ export const useRemoveDeployment = () => {
}

const client = await createGhostcloudRpcClient(
hexToBytes(await store.getPrivateKey()),
fromHex(await store.getPrivateKey()),
)
const msg = await removeDeploymentMsg(name, creator)
const gasEstimation = await client.simulate(creator, [msg], "")
Expand All @@ -259,34 +260,33 @@ export const useRemoveDeployment = () => {
return useMutation({
mutationFn: remove,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: "metas" })
queryClient.invalidateQueries({ queryKey: "balance" })
queryClient.invalidateQueries({ queryKey: ["metas"] })
queryClient.invalidateQueries({ queryKey: ["userBalance"] })
},
})
}

const pageLimit = 10

// Query the Ghostcloud RPC endpoint for deployments created by the current user
// Query the Ghostcloud REST endpoint for deployments created by the current user
export const useFetchMetas = (): [
UseQueryResult<QueryMetasResponse | undefined, unknown>,
UseQueryResult<QueryMetasResponseSDKType | undefined, unknown>,
number,
number,
(direction: string) => void,
] => {
const [pageCount, setPageCount] = React.useState<number>(0)
const [page, setPage] = React.useState(0)
const store = useWeb3AuthStore()
const displayError = useDisplayError()
const { lcdQueryClient } = useLcdQueryClient()

const list = async () => {
const address = await store.getAddress()
if (address) {
const { createRPCQueryClient } = ghostcloud.ClientFactory
const client = await createRPCQueryClient({
rpcEndpoint: GHOSTCLOUD_RPC_TARGET,
})
if (!lcdQueryClient) {
throw new Error("LCD Client not ready")
}

if (address) {
const filter = ghostcloud.ghostcloud.Filter.fromPartial({
field: ghostcloud.ghostcloud.Filter_Field.CREATOR,
operator: ghostcloud.ghostcloud.Filter_Operator.EQUAL,
Expand All @@ -301,7 +301,7 @@ export const useFetchMetas = (): [
filters: [filter],
pagination,
})
const res = await client.ghostcloud.ghostcloud.metas(request)
const res = await lcdQueryClient.ghostcloud.ghostcloud.metas(request)

if (res.pagination?.total ?? 0 > 0) {
setPageCount(Math.ceil(Number(res.pagination?.total) / pageLimit))
Expand All @@ -314,10 +314,10 @@ export const useFetchMetas = (): [
const query = useQuery({
queryKey: ["metas", page],
queryFn: list,
onError: error => {
displayError("Failed to fetch deployments", error as Error)
meta: {
errorMessage: "Failed to fetch deployments",
},
keepPreviousData: true,
placeholderData: keepPreviousData,
})

const handlePageClick = (direction: string) => {
Expand All @@ -333,58 +333,54 @@ export const useFetchMetas = (): [

export const useFetchBalance = (): UseQueryResult<Coin, Error> => {
const store = useWeb3AuthStore()
const displayError = useDisplayError()
const { lcdQueryClient } = useLcdQueryClient()

const fetchBalance = async () => {
if (!lcdQueryClient) {
throw new Error("LCD Client not ready")
}

const address = await store.getAddress()
if (address) {
const { createRPCQueryClient } = cosmos.ClientFactory
const client = await createRPCQueryClient({
rpcEndpoint: GHOSTCLOUD_RPC_TARGET,
})

// Replace this with the actual method to fetch the balance
const request = cosmos.bank.v1beta1.QueryBalanceRequest.fromPartial({
address: address,
const response = await lcdQueryClient.cosmos.bank.v1beta1.balance({
address,
denom: GHOSTCLOUD_DENOM,
})
const response = await client.cosmos.bank.v1beta1.balance(request)

if (response.balance) {
return response.balance
} else {
throw new Error("Failed to fetch balance")
throw new Error("No balance available")
}
}
}

return useQuery({
queryKey: "balance",
queryKey: ["userBalance"],
queryFn: fetchBalance,
onError: error => {
displayError("Failed to fetch balance", error)
meta: {
errorMessage: "Failed to fetch balance",
},
})
}

export const useFetchAddress = (): UseQueryResult<string, Error> => {
const store = useWeb3AuthStore()
const displayError = useDisplayError()

const fetchAddress = async () => {
const address = await store.getAddress()
if (address) {
return address
} else {
throw new Error("Failed to fetch address")
throw new Error("No address available")
}
}

return useQuery({
queryKey: "address",
queryKey: ["address"],
queryFn: fetchAddress,
onError: error => {
displayError("Failed to fetch address", error)
meta: {
errorMessage: "Failed to fetch address",
},
})
}
6 changes: 3 additions & 3 deletions lib/web3-auth.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Web3Auth } from "@web3auth/modal"
import { OpenloginAdapter } from "@web3auth/openlogin-adapter"
import {
WEB3AUTH_ADAPTER_SETTINGS,
WEB3AUTH_CLIENT_ID,
Expand All @@ -11,6 +10,7 @@ import useWeb3AuthStore from "../store/web3-auth"
import { CustomChainConfig } from "@web3auth/base"
import { UIConfig } from "@web3auth/ui"
import { CommonPrivateKeyProvider } from "@web3auth/base-provider"
import { AuthAdapter } from "@web3auth/auth-adapter"

// Initialize the Web3Auth provider using the provided chain and UI configs.
// This function initializes the Web3Auth login modal and connects to the provider.
Expand All @@ -32,11 +32,11 @@ export async function web3AuthInitProvider(
uiConfig: uiConfig,
privateKeyProvider: commonPrivateKeyProvider,
})
const openloginAdapter = new OpenloginAdapter({
const authAdapter = new AuthAdapter({
adapterSettings: WEB3AUTH_ADAPTER_SETTINGS,
loginSettings: WEB3AUTH_LOGIN_SETTINGS,
})
web3auth.configureAdapter(openloginAdapter)
web3auth.configureAdapter(authAdapter)

await web3auth.initModal({
modalConfig: WEB3AUTH_MODAL_CONFIG,
Expand Down
1 change: 0 additions & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
const nextConfig = {
output: 'standalone',
reactStrictMode: true,
swcMinify: true,
typescript: {
ignoreBuildErrors: true,
},
Expand Down
Loading