Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# --------------------------------- REQUIRED --------------------------------- #
# The identifier of the chain the client is running on
# e.g. "dev" for the anvil node, or any chain the game is deployed on, with some config specified in `packages/core/src/network/config/chainConfigs.ts`
PRI_CHAIN_ID="dev"
PRI_CHAIN_ID=216

# This will grant access to the Game Tools browser (for the editor and cheat codes) and Mud Dev Tools
PRI_DEV="true"
Expand Down
2 changes: 2 additions & 0 deletions packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
"@amplitude/analytics-browser": "^2.1.3",
"@fontsource/silkscreen": "^5.0.18",
"@fontsource/space-mono": "^5.0.14",
"@happy.tech/core": "^0.2.1",
"@happy.tech/react": "^0.2.1",
"@latticexyz/common": "2.0.9",
"@latticexyz/faucet": "2.0.9",
"@latticexyz/protocol-parser": "2.0.9",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 8 additions & 26 deletions packages/client/src/AppLoadingState.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect, useMemo } from "react";
import { BrowserRouter, Navigate, Route, Routes, useLocation } from "react-router-dom";
import { toast } from "react-toastify";

import { minEth } from "@primodiumxyz/core";
import { useAccountClient, useSyncStatus } from "@primodiumxyz/core/react";
Expand All @@ -13,42 +14,23 @@ import { Sandbox } from "@/screens/Sandbox";
import { Statistics } from "@/screens/Statistics";

export default function AppLoadingState() {
const { playerBalanceData, sessionBalanceData, requestDrip } = useDripAccount();
const { playerBalanceData, sessionBalanceData } = useDripAccount();
const { sessionAccount, playerAccount } = useAccountClient();

useEffect(() => {
const sessionBalance = sessionBalanceData.data?.value;
if (!sessionAccount?.address || sessionBalanceData.isLoading || !sessionBalance || sessionBalance >= minEth) return;
console.log("dripping session account");
requestDrip(sessionAccount.address);
}, [sessionAccount?.address, sessionBalanceData.data?.value, sessionBalanceData.isLoading]);

useEffect(() => {
const playerBalance = playerBalanceData.data?.value;
if (sessionBalanceData.isLoading || !playerBalance || playerBalance >= minEth) return;
console.log("dripping player account");
requestDrip(playerAccount.address);
}, [playerAccount.address, sessionBalanceData.isLoading, playerBalanceData.data?.value]);

const { loading, error, progress, message } = useSyncStatus(playerAccount.entity);
const balanceReady = useMemo(() => {
const playerBalanceReady = (playerBalanceData.data?.value ?? 0n) >= minEth;
const sessionBalanceReady = !sessionAccount || (sessionBalanceData.data?.value ?? 0n) >= minEth;
return playerBalanceReady && sessionBalanceReady;
}, [loading, playerBalanceData, sessionAccount, sessionBalanceData]);

useEffect(() => {
if (!balanceReady) toast.warn("Please top up your $HAPPY balance.");
}, [balanceReady]);

return (
<div className="h-screen relative">
{!error && (
<div className="relative">
{!loading && !balanceReady && (
<div className="flex flex-col items-center justify-center h-screen text-white gap-4">
<p className="text-lg text-white">
<span className="">Dripping Eth to Primodium account</span>
<span>&hellip;</span>
</p>
<Progress value={100} max={100} className="animate-pulse w-56" />
</div>
)}
{loading && (
<div className="flex items-center justify-center h-screen">
<div className="flex flex-col items-center gap-4">
Expand All @@ -68,7 +50,7 @@ export default function AppLoadingState() {
</div>
</div>
)}
{!loading && balanceReady && (
{!loading && (
<BrowserRouter>
<PrimodiumRoutes />
</BrowserRouter>
Expand Down
66 changes: 4 additions & 62 deletions packages/client/src/Connect.tsx
Original file line number Diff line number Diff line change
@@ -1,86 +1,28 @@
import { chunk } from "lodash";
import React, { useEffect, useState } from "react";
import { FaExclamationTriangle } from "react-icons/fa";
import React, { useEffect } from "react";
import { toast } from "react-toastify";
import { useAccount, useConnect } from "wagmi";

import { usePersistentStore } from "@primodiumxyz/game/src/stores/PersistentStore";
import { Landing } from "@/screens/Landing";

const connectorIcons: Record<string, string> = {
["MetaMask"]: "/img/icons/web3/metamask.svg",
["WalletConnect"]: "/img/icons/web3/walletconnect.svg",
["Coinbase Wallet"]: "/img/icons/web3/coinbase.svg",
["HappyChain Wagmi Provider"]: "/img/icons/web3/happychain.png", // [HAPPY_PRIM] new icon, provided name is configured within the package
};

/** [HAPPY_PRIM] We only show the happychain connector here since we want them to play using the HappyWallet! */
export const Connect: React.FC = React.memo(() => {
const { connector, isConnected } = useAccount();
const { connect, connectors, error, isPending } = useConnect();
const { noExternalAccount, setNoExternalAccount } = usePersistentStore();
const [showingToast, setShowingToast] = useState(false);

useEffect(() => {
if (error) toast.warn(error.message);
}, [error]);

const confirmToast = async () => {
toast.dismiss();
if (showingToast) await new Promise((resolve) => setTimeout(resolve, 500));
setShowingToast(true);
toast(
({ closeToast }) => (
<div className="flex flex-col gap-4">
<div className="flex flex-col text-center justify-center items-center gap-2 w-full">
<FaExclamationTriangle size={24} className="text-warning" />
Are you sure you want to login as guest? You will not be able to win prizes or play across devices.
</div>

<div className="flex justify-center w-full gap-2">
<button
className="btn btn-secondary btn-xs"
onClick={() => {
setNoExternalAccount(true);
closeToast && closeToast();
}}
>
Confirm
</button>
<button
onClick={() => {
setShowingToast(false);
closeToast && closeToast();
}}
className="btn btn-primary btn-xs"
>
Cancel
</button>
</div>
</div>
),
{
// className: "border-error",
position: "top-center",
autoClose: false,
closeOnClick: false,
draggable: false,
closeButton: false,
hideProgressBar: true,
},
);
};

if (isConnected || noExternalAccount) return null;
if (isConnected) return null;

return (
<Landing>
<div className="flex flex-col gap-2 w-full">
<button
className="btn-lg btn-secondary star-background w-full btn join-item inline pointer-events-auto font-bold outline-none h-fit z-10"
onClick={confirmToast}
>
Login as Guest
</button>

{chunk(
connectors.filter((x) => x.id !== connector?.id),
2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const TransferSelect = ({ side }: { side: "left" | "right" }) => {
))}
</div>
{showNewFleet && (
<div className="h-[5.5rem] gap-2 border-t border-t-primary mt-1 border-t-2 flex justify-center items-center flex-col">
<div className="h-[5.5rem] gap-2 border-t-2 border-t-primary mt-1 flex justify-center items-center flex-col">
{!canBuildFleet && (
<p className="opacity-70 text-sm text-center">
Reached Max Fleet Count. Build a Starmapper Station to build more fleets.
Expand Down
15 changes: 12 additions & 3 deletions packages/client/src/config/getCoreConfig.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import worldsJson from "contracts/worlds.json";
import { Address, Hex } from "viem";

import { chainConfigs, CoreConfig } from "@primodiumxyz/core";
import { ChainConfig, chainConfigs, CoreConfig } from "@primodiumxyz/core";

const worlds = worldsJson as Partial<Record<string, { address: string; blockNumber?: number }>>;

const findChainById = (id: number | string): ChainConfig => {
const chain = Object.values(chainConfigs).find((chain) => chain.id === Number(id));
if (!chain) {
throw new Error(`No chain found with ID ${id}`);
}
return chain;
};

export const getCoreConfig = (): CoreConfig => {
// Ignore deployment URL params on production subdomains (primodium.com)
const params = window.location.hostname.endsWith("primodium.com")
? new URLSearchParams()
: new URLSearchParams(window.location.search);

const chainId = (params.get("chainid") || import.meta.env.PRI_CHAIN_ID || "dev") as keyof typeof chainConfigs;
const chainId = params.get("chainid") || import.meta.env.PRI_CHAIN_ID || "dev";
const chain = findChainById(chainId);

const chain = chainConfigs[chainId];
console.log(chain);

const world = worlds[chain.id];
const worldAddress = (params.get("worldAddress") || world?.address) as Address;
Expand Down
26 changes: 4 additions & 22 deletions packages/client/src/config/wagmiConfig.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,5 @@
import { createClient } from "viem";
import { createConfig, http } from "wagmi";
import { coinbaseWallet, walletConnect } from "wagmi/connectors";
import { createHappyChainWagmiConfig, happyChainSepolia } from "@happy.tech/core";
import { Config } from "wagmi";

import { getCoreConfig } from "@/config/getCoreConfig";

const env = import.meta.env;
const projectId = env.PRI_WALLETCONNECT_PROJECT_ID;

const { chain } = getCoreConfig();

export const wagmiConfig = createConfig({
chains: [chain],

client({ chain }) {
return createClient({ chain, transport: http() });
},
connectors: [
walletConnect({ projectId }),
coinbaseWallet({ appName: "wagmi" }),
// injected({target: 'Injected', shimDisconnect: true}),
],
});
// [HAPPY_PRIM] use custom config tailored to HappyChain
export const wagmiConfig: Config = createHappyChainWagmiConfig(happyChainSepolia);
8 changes: 6 additions & 2 deletions packages/client/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { HappyWalletProvider } from "@happy.tech/react";
import { Analytics } from "@vercel/analytics/react";
import ReactDOM from "react-dom/client";

Expand All @@ -9,9 +10,12 @@ const rootElement = document.getElementById("react-root");
if (!rootElement) throw new Error("React root not found");
const root = ReactDOM.createRoot(rootElement);

// [HAPPY_PRIM] wrap app + inject wallet using the HProvider
root.render(
<>
<App />
<Analytics />
<HappyWalletProvider>
<App />
<Analytics />
</HappyWalletProvider>
</>,
);
2 changes: 1 addition & 1 deletion packages/client/src/screens/Enter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export const Enter: React.FC = () => {

return (
<Landing>
<TransactionQueueMask queueItemId={defaultEntity} className="w-4/5 z-20">
<TransactionQueueMask queueItemId={defaultEntity} className="w-4/5 z-20 space-y-2">
{state === "delegate" && (
<div className="grid grid-cols-7 gap-2 items-center pointer-events-auto">
<button
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/network/config/chainConfigs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const baseSepolia: ChainConfig = {

export const happyChainSepolia: ChainConfig = {
...happyChainDef,
indexerUrl: "http://localhost:3001", // ## [happyTODO :: deploy indexer and then add the URL here] ##
indexerUrl: "https://primodium-indexer.happy.tech",
};

export type ChainConfig = MUDChain & { indexerUrl?: string };
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/txExecute/_execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export async function _execute({ network: { waitForTransaction, publicClient } }

try {
const txHash = await txPromise;
// await waitForTransaction(txHash); // doesn't work
await waitForTransaction(txHash);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was earlier commented out since it was giving an error for not being able to fetch a receipt → the fix here (made earlier but untested for this flow) to initialise the publicClient in createNetwork using a custom connector with the happyProvider

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

console.log("[Tx] hash: ", txHash);

// If the transaction runs out of gas, status will be reverted
Expand Down
23 changes: 21 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading