Skip to content

Commit

Permalink
rework config
Browse files Browse the repository at this point in the history
  • Loading branch information
holic committed Apr 18, 2024
1 parent 6f8afcb commit c0383ee
Show file tree
Hide file tree
Showing 16 changed files with 243 additions and 144 deletions.
32 changes: 2 additions & 30 deletions packages/account-kit/src/AccountKitProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,6 @@
import { createContext, useContext, type ReactNode } from "react";
import { Address } from "viem";
import { MUDChain } from "@latticexyz/common/chains";
import { AccountModal } from "./AccountModal";

export type Config = {
readonly chain: MUDChain;
readonly worldAddress: Address;
/**
* Address of the `GasTank` paymaster. Defaults to `chain.contracts.gasTank.address` if set.
* @link http://www.npmjs.com/package/@latticexyz/gas-tank
*/
readonly gasTankAddress?: Address;
readonly appInfo?: {
readonly name?: string;
/**
* The app icon used throughout the onboarding process. It will be used as a fallback if no `image` is provided. Icon should be 1:1 aspect ratio, at least 200x200.
*/
readonly icon?: string;
/**
* The image displayed during the first step of onboarding. Ideally around 600x250.
*/
readonly image?: string;
};
theme?: "dark" | "light";
};
import { Config } from "./config";

/** @internal */
const Context = createContext<Config | null>(null);
Expand All @@ -37,12 +14,7 @@ export function AccountKitProvider({ config, children }: Props) {
const currentConfig = useContext(Context);
if (currentConfig) throw new Error("`AccountKitProvider` can only be used once.");
return (
<Context.Provider
value={{
...config,
gasTankAddress: config.gasTankAddress ?? config.chain.contracts?.gasTank?.address,
}}
>
<Context.Provider value={config}>
{children}
<AccountModal />
</Context.Provider>
Expand Down
77 changes: 77 additions & 0 deletions packages/account-kit/src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { MUDChain } from "@latticexyz/common/chains";
import { satisfy } from "@latticexyz/common/type-utils";
import { Transport } from "viem";
import { Address } from "viem/accounts";

export type PaymasterType = "gasTank";
export type PaymasterBase = { readonly type: PaymasterType; readonly address: Address };

/**
* @link http://www.npmjs.com/package/@latticexyz/gas-tank
*/
export type GasTankPaymaster = {
readonly type: "gasTank";
/**
* Address of the `GasTank` paymaster. Defaults to `chain.contracts.gasTank.address` if set.
* @link http://www.npmjs.com/package/@latticexyz/gas-tank
*/
readonly address: Address;
};

export type Paymaster = satisfy<PaymasterBase, GasTankPaymaster>;

export type Erc4337Config = {
/**
* viem `Transport` for ERC-4337-specific RPC methods (e.g. `eth_sendUserOperation`).
*
* If not set, defaults to `http(chain.rpcUrls.erc4337Bundler.http[0])`.
*/
readonly transport: Transport;
/**
* List of ERC-4337 paymasters.
*
* If not set, defaults to `gasTank` paymaster using `chain.contracts.gasTank.address`.
*/
readonly paymasters: readonly [Paymaster, ...Paymaster[]];
};

export type Config = {
/**
* The chain the world is deployed to. This is the chain used to return an app account client once fully signed in.
*/
readonly chain: MUDChain;
/*
* The world address.
*/
readonly worldAddress: Address;

/**
* Account Kit UI theme.
*
* If not set, defaults to OS' light or dark mode.
*/
theme?: "dark" | "light";

readonly appInfo?: {
/**
* The app name.
*
* If not set, defaults to page's `<title>`.
*/
readonly name?: string;
/**
* The app icon used throughout the onboarding process. It will be used as a fallback if no `image` is provided. Icon should be 1:1 aspect ratio, at least 200x200.
*
* If not set, defaults to the page's `<link rel="icon">` or the origin's `/favicon.ico`.
*/
readonly icon?: string;
/**
* The splash image displayed during the first step of onboarding. Ideally around 600x250.
*
* If not set, defaults to displaying the name, icon, and origin.
*/
readonly image?: string;
};

readonly erc4337?: Erc4337Config | false;
};
7 changes: 5 additions & 2 deletions packages/account-kit/src/steps/gas-tank/GasSpenderContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
import { Button } from "../../ui/Button";
import { AccountModalSection } from "../../AccountModalSection";
import { useOnboardingSteps } from "../../useOnboardingSteps";
import { usePaymaster } from "../../usePaymaster";

export function GasSpenderContent() {
const queryClient = useQueryClient();
const { chain, gasTankAddress } = useConfig();
const { chain } = useConfig();
const gasTank = usePaymaster("gasTank");
const publicClient = usePublicClient({ chainId: chain.id });
const { data: userAccountClient } = useWalletClient({ chainId: chain.id });
const appAccountClient = useAppAccountClient();
Expand All @@ -24,11 +26,12 @@ export function GasSpenderContent() {
if (!publicClient) throw new Error("Public client not ready. Not connected?");
if (!userAccountClient) throw new Error("Wallet client not ready. Not connected?");
if (!appAccountClient) throw new Error("App account client not ready.");
if (!gasTank) throw new Error("No gas tank configured.");

console.log("registerSpender");
const hash = await callWithSignature({
chainId: chain.id,
worldAddress: gasTankAddress,
worldAddress: gasTank.address,
systemId: resourceToHex({ type: "system", namespace: "", name: "PaymasterSystem" }),
callData: encodeFunctionData({
abi: GasTankAbi,
Expand Down
10 changes: 6 additions & 4 deletions packages/account-kit/src/steps/gas-tank/RelayLinkContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Button } from "../../ui/Button";
import { parseEther } from "viem";
import { createRelayClient } from "./utils/createRelayClient";
import { useConfig } from "../../AccountKitProvider";
import { usePaymaster } from "../../usePaymaster";

createRelayClient();

Expand All @@ -15,7 +16,8 @@ type RelayLinkContentProps = {

export function RelayLinkContent({ amount }: RelayLinkContentProps) {
const wallet = useWalletClient();
const { chain, gasTankAddress } = useConfig();
const { chain } = useConfig();
const gasTank = usePaymaster("gasTank");
const userAccount = useAccount();
const userAccountChainId = userAccount?.chain?.id;
const publicClient = usePublicClient({
Expand Down Expand Up @@ -51,12 +53,12 @@ export function RelayLinkContent({ amount }: RelayLinkContentProps) {
}, [amount, wallet.data, chain, selectedSourceChainId]);

const executeDeposit = useCallback(async () => {
if (!wallet.data || !amount || selectedSourceChainId == null || !publicClient) return;
if (!wallet.data || !amount || selectedSourceChainId == null || !publicClient || !gasTank) return;

await wallet.data.switchChain({ id: selectedSourceChainId });

const { request } = await publicClient.simulateContract({
address: gasTankAddress,
address: gasTank.address,
abi: GasTankAbi,
functionName: "depositTo",
args: [wallet.data.account.address],
Expand All @@ -77,7 +79,7 @@ export function RelayLinkContent({ amount }: RelayLinkContentProps) {
}
},
});
}, [wallet.data, amount, selectedSourceChainId, publicClient, gasTankAddress, chain.id]);
}, [wallet.data, amount, selectedSourceChainId, publicClient, gasTank, chain.id]);

const handleSubmit = async (evt: React.FormEvent<HTMLFormElement>) => {
evt.preventDefault();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { nativeDeposit } from "./nativeDeposit";
import { relayLinkDeposit } from "./relayLinkDeposit";
import { useGasTankBalance } from "../../../useGasTankBalance";
import { usePrevious } from "../../../utils/usePrevious";
import { usePaymaster } from "../../../usePaymaster";

export type StatusType = "pending" | "loading" | "loadingL2" | "success" | "error" | "idle";

Expand Down Expand Up @@ -69,7 +70,8 @@ function reducer(state: StateType, action: ActionType): StateType {

export const useDepositHandler = (depositMethod: DepositMethod) => {
const [state, dispatch] = useReducer(reducer, initialState);
const { chain, gasTankAddress } = useConfig();
const { chain } = useConfig();
const gasTank = usePaymaster("gasTank");
const wagmiConfig = useWagmiConfig();
const wallet = useWalletClient();
const userAccount = useAccount();
Expand All @@ -86,7 +88,7 @@ export const useDepositHandler = (depositMethod: DepositMethod) => {

const deposit = useCallback(
async (amount: string) => {
if (!wallet.data || !userAccountAddress || !userAccountChainId || !gasTankAddress || !amount) return;
if (!wallet.data || !userAccountAddress || !userAccountChainId || !amount || !gasTank) return;

try {
dispatch({ type: "SET_STATUS", payload: "pending" });
Expand All @@ -95,7 +97,7 @@ export const useDepositHandler = (depositMethod: DepositMethod) => {
const txHash = await directDeposit({
config: wagmiConfig,
chainId: chain.id,
gasTankAddress,
gasTankAddress: gasTank.address,
userAccountAddress,
amount,
});
Expand All @@ -108,7 +110,7 @@ export const useDepositHandler = (depositMethod: DepositMethod) => {
config: wagmiConfig,
wallet,
chainId: userAccountChainId,
gasTankAddress,
gasTankAddress: gasTank.address,
userAccountAddress,
amount,
});
Expand All @@ -123,7 +125,7 @@ export const useDepositHandler = (depositMethod: DepositMethod) => {
config: wagmiConfig,
chainId: userAccountChainId,
toChainId: chain.id,
gasTankAddress,
gasTankAddress: gasTank.address,
wallet,
amount,
onProgress: (data1, data2, data3, data4, data5) => {
Expand All @@ -141,7 +143,7 @@ export const useDepositHandler = (depositMethod: DepositMethod) => {
dispatch({ type: "SET_ERROR", payload: error });
}
},
[userAccountAddress, depositMethod, wagmiConfig, chain.id, gasTankAddress, wallet, userAccountChainId],
[userAccountAddress, depositMethod, wagmiConfig, chain.id, gasTank, wallet, userAccountChainId],
);

return useMemo(() => {
Expand Down
29 changes: 0 additions & 29 deletions packages/account-kit/src/steps/gas-tank/hooks/useEstimatedFees.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useConfig } from "../../../AccountKitProvider";
import { encodeFullNativeDeposit } from "./nativeDeposit";
import { OPTIMISM_PORTAL_ADDRESS } from "../constants";
import { fetchRelayLinkQuote } from "./relayLinkDeposit";
import { usePaymaster } from "../../../usePaymaster";

const estimateDirectFee = async ({
config,
Expand Down Expand Up @@ -80,7 +81,9 @@ const estimateNativeFee = async ({

export const useTransactionFees = (amount: string, depositMethod: DepositMethod) => {
const [fees, setFees] = useState<string>("");
const { chain, gasTankAddress } = useConfig();
const { chain } = useConfig();
const gasTank = usePaymaster("gasTank");
if (!gasTank) throw new Error("No gas tank configured.");
const wagmiConfig = useWagmiConfig();
const userAccount = useAccount();
const userAccountAddress = userAccount.address;
Expand All @@ -93,7 +96,7 @@ export const useTransactionFees = (amount: string, depositMethod: DepositMethod)
fees = await estimateDirectFee({
config: wagmiConfig,
chainId: userAccountChainId,
gasTankAddress,
gasTankAddress: gasTank.address,
userAccountAddress,
});

Expand All @@ -102,7 +105,7 @@ export const useTransactionFees = (amount: string, depositMethod: DepositMethod)
fees = await estimateNativeFee({
config: wagmiConfig,
chainId: userAccountChainId,
gasTankAddress,
gasTankAddress: gasTank.address,
userAccountAddress,
});

Expand All @@ -120,7 +123,7 @@ export const useTransactionFees = (amount: string, depositMethod: DepositMethod)
};

fetchFees();
}, [amount, chain, depositMethod, gasTankAddress, userAccountAddress, userAccountChainId, wagmiConfig]);
}, [amount, chain, depositMethod, gasTank, userAccountAddress, userAccountChainId, wagmiConfig]);

return {
fees,
Expand Down
Loading

0 comments on commit c0383ee

Please sign in to comment.