Skip to content

Commit 9eb4971

Browse files
committed
Refactor connection context
1 parent a7147f5 commit 9eb4971

27 files changed

+179
-150
lines changed

packages/keychain/global.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Controller } from "@/utils/controller";
1+
import Controller from "./src/utils/controller";
22

33
declare global {
44
interface Window {

packages/keychain/src/components/DeployController.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { ControllerError } from "@/utils/connection";
2121
import { TransactionSummary } from "@/components/transaction/TransactionSummary";
2222
import { ETH_CONTRACT_ADDRESS, useERC20Balance } from "@cartridge/utils";
2323
import { Link } from "react-router-dom";
24+
import { useController } from "@/hooks/controller";
2425

2526
export function DeployController({
2627
onClose,
@@ -29,7 +30,8 @@ export function DeployController({
2930
onClose: () => void;
3031
ctrlError?: ControllerError;
3132
}) {
32-
const { controller, chainName, hasPrefundRequest } = useConnection();
33+
const { chainName, hasPrefundRequest } = useConnection();
34+
const { controller } = useController();
3335
const { deploySelf, isDeploying } = useDeploy();
3436
const [deployHash, setDeployHash] = useState<string>();
3537
const [error, setError] = useState<Error>();

packages/keychain/src/components/ExecutionContainer.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { useState, useCallback, useEffect, useRef } from "react";
22
import { Button } from "@cartridge/ui-next";
33
import { Container, Footer } from "@/components/layout";
4-
import { useConnection } from "@/hooks/connection";
54
import { ControllerError } from "@/utils/connection";
65
import { ControllerErrorAlert, ErrorAlert } from "@/components/ErrorAlert";
76
import { Fees } from "./Fees";
@@ -11,6 +10,7 @@ import { ErrorCode } from "@cartridge/account-wasm/controller";
1110
import { BannerProps } from "./layout/container/header/Banner";
1211
import { parseControllerError } from "@/utils/connection/execute";
1312
import isEqual from "lodash/isEqual";
13+
import { useController } from "@/hooks/controller";
1414

1515
interface ExecutionContainerProps {
1616
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -41,7 +41,7 @@ export function ExecutionContainer({
4141
children,
4242
}: ExecutionContainerProps &
4343
Pick<BannerProps, "title" | "description" | "icon">) {
44-
const { controller } = useConnection();
44+
const { controller } = useController();
4545
const [maxFee, setMaxFee] = useState<bigint | null>(null);
4646
const [ctrlError, setCtrlError] = useState<ControllerError | undefined>(
4747
executionError,

packages/keychain/src/components/app.tsx

+17
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,25 @@ import { Pending } from "./pending";
88
import { Consent, Slot } from "./slot";
99
import { OcclusionDetector } from "./OcclusionDetector";
1010
import { Fund } from "./slot/fund";
11+
import { useConnection } from "@/hooks/connection";
12+
import { useController } from "@/hooks/controller";
13+
import { CreateController } from "./connect";
14+
import { LoginMode } from "./connect/types";
1115

1216
export function App() {
17+
const { origin } = useConnection();
18+
const { controller } = useController();
19+
20+
// Only render in iframe with valid origin
21+
if (window.self === window.top || !origin) {
22+
return <></>;
23+
}
24+
25+
// If no controller is set up, show the create controller screen
26+
if (!controller) {
27+
return <CreateController loginMode={LoginMode.Controller} />;
28+
}
29+
1330
return (
1431
<>
1532
<OcclusionDetector />

packages/keychain/src/components/connect/CreateSession.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { UnverifiedSessionSummary } from "@/components/session/UnverifiedSession
1111
import { VerifiedSessionSummary } from "@/components/session/VerifiedSessionSummary";
1212
import { DEFAULT_SESSION_DURATION, NOW } from "@/const";
1313
import { Button, Checkbox } from "@cartridge/ui-next";
14+
import { useController } from "@/hooks/controller";
1415

1516
export function CreateSession({
1617
policies,
@@ -21,7 +22,8 @@ export function CreateSession({
2122
onConnect: (transaction_hash?: string, expiresAt?: bigint) => void;
2223
isUpdate?: boolean;
2324
}) {
24-
const { controller, upgrade, chainId, theme, logout } = useConnection();
25+
const { upgrade, chainId, theme, logout } = useConnection();
26+
const { controller } = useController();
2527
const [isConnecting, setIsConnecting] = useState(false);
2628
const [isConsent, setIsConsent] = useState(false);
2729
const [duration, setDuration] = useState<bigint>(DEFAULT_SESSION_DURATION);

packages/keychain/src/components/connect/RegisterSession.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { DEFAULT_SESSION_DURATION, NOW } from "@/const";
1111
import { UnverifiedSessionSummary } from "@/components/session/UnverifiedSessionSummary";
1212
import { VerifiedSessionSummary } from "@/components/session/VerifiedSessionSummary";
1313
import { ParsedSessionPolicies } from "@/hooks/session";
14+
import { useController } from "@/hooks/controller";
1415

1516
export function RegisterSession({
1617
policies,
@@ -21,7 +22,8 @@ export function RegisterSession({
2122
onConnect: (transaction_hash: string, expiresAt: bigint) => void;
2223
publicKey?: string;
2324
}) {
24-
const { controller, theme } = useConnection();
25+
const { theme } = useConnection();
26+
const { controller } = useController();
2527
const [duration, setDuration] = useState<bigint>(DEFAULT_SESSION_DURATION);
2628
const [transactions, setTransactions] = useState<
2729
| {

packages/keychain/src/components/connect/Upgrade.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ import { BoltIcon, CircleIcon } from "@cartridge/ui-next";
22
import { ExecutionContainer } from "@/components/ExecutionContainer";
33
import { Content } from "@/components/layout";
44
import { useConnection } from "@/hooks/connection";
5+
import { useController } from "@/hooks/controller";
56

67
export const Upgrade = () => {
7-
const { upgrade, controller } = useConnection();
8+
const { upgrade } = useConnection();
9+
const { controller } = useController();
810

911
return (
1012
<ExecutionContainer

packages/keychain/src/components/connect/create/useCreateController.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Controller from "@/utils/controller";
77
import { fetchAccount } from "./utils";
88
import { PopupCenter } from "@/utils/url";
99
import { useAccountQuery } from "@cartridge/utils/api/cartridge";
10+
import { useController } from "@/hooks/controller";
1011

1112
export function useCreateController({
1213
onCreated,
@@ -20,7 +21,8 @@ export function useCreateController({
2021
const [isLoading, setIsLoading] = useState(false);
2122
const [error, setError] = useState<Error>();
2223
const [pendingUsername, setPendingUsername] = useState<string>();
23-
const { origin, policies, chainId, rpcUrl, setController } = useConnection();
24+
const { origin, policies, chainId, rpcUrl } = useConnection();
25+
const { setController } = useController();
2426

2527
useAccountQuery(
2628
{ username: pendingUsername || "" },
@@ -77,7 +79,6 @@ export function useCreateController({
7779
credentialId,
7880
});
7981

80-
window.controller = controller;
8182
setController(controller);
8283
onCreated?.();
8384
},

packages/keychain/src/components/funding/DepositEth.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import { TokenPair, usePriceQuery } from "@cartridge/utils/api/cartridge";
3636
import { ETH_CONTRACT_ADDRESS } from "@cartridge/utils";
3737
import { toast } from "sonner";
3838
import { DEFAULT_AMOUNT } from "./constants";
39+
import { useController } from "@/hooks/controller";
3940

4041
type DepositEthProps = {
4142
onComplete?: (deployHash?: string) => void;
@@ -52,7 +53,8 @@ export function DepositEth(innerProps: DepositEthProps) {
5253

5354
function DepositEthInner({ onComplete, onBack }: DepositEthProps) {
5455
const { connectAsync, connectors, isPending: isConnecting } = useConnect();
55-
const { controller, chainId } = useConnection();
56+
const { chainId } = useConnection();
57+
const { controller } = useController();
5658
const { account: extAccount } = useAccount();
5759

5860
const [dollarAmount, setDollarAmount] = useState<number>(DEFAULT_AMOUNT);
@@ -245,7 +247,7 @@ function DepositEthInner({ onComplete, onBack }: DepositEthProps) {
245247

246248
function ExternalWalletProvider({ children }: PropsWithChildren) {
247249
const { connectors } = useInjectedConnectors({});
248-
const { controller } = useConnection();
250+
const { controller } = useController();
249251

250252
if (!controller) {
251253
return children;

packages/keychain/src/components/funding/PurchaseCredits.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { Balance } from "./Balance";
1616
import CheckoutForm from "./StripeCheckout";
1717
import { isIframe } from "@cartridge/utils";
1818
import { DEFAULT_AMOUNT } from "./constants";
19+
import { useController } from "@/hooks/controller";
1920

2021
const STRIPE_API_PUBKEY =
2122
"pk_test_51Kr6IXIS6lliDpf33KnwWDtIjRPWt3eAI9CuSLR6Vvc3GxHEwmSU0iszYbUlgUadSRluGKAFphe3JzltyjPAKiBK00al4RAFQu";
@@ -32,7 +33,8 @@ type PurchaseCreditsProps = {
3233
};
3334

3435
export function PurchaseCredits({ isSlot, onBack }: PurchaseCreditsProps) {
35-
const { controller, closeModal } = useConnection();
36+
const { closeModal } = useConnection();
37+
const { controller } = useController();
3638

3739
const [clientSecret, setClientSecret] = useState("");
3840
const [isLoading, setisLoading] = useState<boolean>(false);

packages/keychain/src/components/funding/index.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Container, Content, Footer } from "@/components/layout";
22
import { useState } from "react";
3-
import { useConnection } from "@/hooks/connection";
43
import {
54
Button,
65
ArrowIcon,
@@ -11,6 +10,7 @@ import {
1110
import { DepositEth } from "./DepositEth";
1211
import { PurchaseCredits } from "./PurchaseCredits";
1312
import { Balance, BalanceType } from "./Balance";
13+
import { useController } from "@/hooks/controller";
1414

1515
const enum FundingState {
1616
SHOW_OPTIONS,
@@ -25,7 +25,7 @@ export type FundingProps = {
2525
};
2626

2727
export function Funding({ title, isSlot, onComplete }: FundingProps) {
28-
const { controller } = useConnection();
28+
const { controller } = useController();
2929
const [state, setState] = useState<FundingState>(FundingState.SHOW_OPTIONS);
3030
const showBalances: BalanceType[] = isSlot ? ["credits"] : ["credits", "eth"];
3131
const showCredits =

packages/keychain/src/components/home.tsx

+16-23
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,23 @@ import { ResponseCodes } from "@cartridge/controller";
44
import { useConnection } from "@/hooks/connection";
55
import { DeployCtx, ExecuteCtx, SignMessageCtx } from "@/utils/connection";
66
import { ConfirmTransaction } from "./transaction/ConfirmTransaction";
7-
import { CreateController, CreateSession, Logout, Upgrade } from "./connect";
8-
import { LoginMode } from "./connect/types";
7+
import { CreateSession, Logout, Upgrade } from "./connect";
98
import { DeployController } from "./DeployController";
109
import { ErrorPage } from "./ErrorBoundary";
1110
import { PurchaseCredits } from "./funding/PurchaseCredits";
1211
import { Settings } from "./settings";
1312
import { SignMessage } from "./SignMessage";
1413
import { PageLoading } from "./Loading";
1514
import { execute } from "@/utils/connection/execute";
16-
import { usePostHog } from "@/hooks/posthog";
15+
import { useController } from "@/hooks/controller";
1716

1817
export function Home() {
19-
const { context, setContext, controller, error, policies, upgrade } =
20-
useConnection();
18+
const { context, setContext, error, policies, upgrade } = useConnection();
19+
const { controller } = useController();
20+
2121
const [hasSessionForPolicies, setHasSessionForPolicies] = useState<
2222
boolean | undefined
2323
>(undefined);
24-
const posthog = usePostHog();
25-
2624
useEffect(() => {
2725
if (controller && policies) {
2826
controller.isRequestedSession(policies).then((isRequestedSession) => {
@@ -33,29 +31,19 @@ export function Home() {
3331
}
3432
}, [controller, policies]);
3533

36-
useEffect(() => {
37-
if (context?.type) {
38-
posthog?.capture(
39-
`Call ${context.type.charAt(0).toUpperCase() + context.type.slice(1)}`,
40-
);
41-
}
42-
}, [context?.type, posthog]);
43-
44-
if (window.self === window.top || !context?.origin) {
45-
return <></>;
46-
}
47-
4834
if (error) {
4935
return <ErrorPage error={error} />;
5036
}
5137

52-
// No controller, send to login
38+
if (!context) {
39+
return <></>;
40+
}
41+
5342
if (!controller) {
54-
return <CreateController loginMode={LoginMode.Controller} />;
43+
return <PageLoading />;
5544
}
5645

5746
if (!upgrade.isSynced || hasSessionForPolicies === undefined) {
58-
// This is likely never observable in a real application but just in case.
5947
return <PageLoading />;
6048
}
6149

@@ -113,7 +101,12 @@ export function Home() {
113101
<SignMessage
114102
origin={ctx.origin}
115103
typedData={ctx.typedData}
116-
onSign={(sig: Signature) => context.resolve(sig)}
104+
onSign={(sig: Signature) =>
105+
ctx.resolve({
106+
code: ResponseCodes.SUCCESS,
107+
...sig,
108+
})
109+
}
117110
onCancel={() =>
118111
ctx.resolve({
119112
code: ResponseCodes.CANCELED,

packages/keychain/src/components/provider/connection.tsx

-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { createContext } from "react";
2-
import Controller from "@/utils/controller";
32
import { ConnectionCtx } from "@/utils/connection";
43
import { UpgradeInterface } from "@/hooks/upgrade";
54
import { ParsedSessionPolicies } from "@/hooks/session";
@@ -11,7 +10,6 @@ export const ConnectionContext = createContext<
1110

1211
export type ConnectionContextValue = {
1312
context: ConnectionCtx;
14-
controller?: Controller;
1513
origin?: string;
1614
rpcUrl?: string;
1715
chainId?: string;
@@ -22,7 +20,6 @@ export type ConnectionContextValue = {
2220
error?: Error;
2321
upgrade: UpgradeInterface;
2422
setContext: (context: ConnectionCtx) => void;
25-
setController: (controller: Controller) => void;
2623
closeModal: () => void;
2724
openModal: () => void;
2825
logout: () => void;

packages/keychain/src/components/provider/posthog.tsx

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import { PropsWithChildren, useEffect } from "react";
22
import { PostHogContext, PostHogWrapper } from "@/context/posthog";
33
import { useConnectionValue } from "@/hooks/connection";
4+
import { useController } from "@/hooks/controller";
45

5-
export function PostHogProvider({ children }: PropsWithChildren) {
6-
const { controller, origin } = useConnectionValue();
6+
export const posthog = new PostHogWrapper(import.meta.env.VITE_POSTHOG_KEY!, {
7+
host: import.meta.env.VITE_POSTHOG_HOST,
8+
persistence: "memory",
9+
autocapture: false,
10+
});
711

8-
const posthog = new PostHogWrapper(import.meta.env.VITE_POSTHOG_KEY!, {
9-
host: import.meta.env.VITE_POSTHOG_HOST,
10-
persistence: "memory",
11-
autocapture: false,
12-
});
12+
export function PostHogProvider({ children }: PropsWithChildren) {
13+
const { origin } = useConnectionValue();
14+
const { controller } = useController();
1315

1416
useEffect(() => {
1517
if (controller) {
@@ -21,13 +23,13 @@ export function PostHogProvider({ children }: PropsWithChildren) {
2123
} else {
2224
posthog.reset();
2325
}
24-
}, [posthog, controller]);
26+
}, [controller]);
2527

2628
useEffect(() => {
2729
if (origin) {
2830
posthog.group("company", origin);
2931
}
30-
}, [posthog, origin]);
32+
}, [origin]);
3133

3234
return (
3335
<PostHogContext.Provider value={{ posthog }}>

packages/keychain/src/components/session.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { useCallback, useEffect, useMemo, useState } from "react";
1111
import { LoginMode } from "@/components/connect/types";
1212
import { PageLoading } from "@/components/Loading";
1313
import { useNavigate, useSearchParams } from "react-router-dom";
14+
import { useController } from "@/hooks/controller";
1415

1516
type SessionResponse = {
1617
username: string;
@@ -44,7 +45,8 @@ export function Session() {
4445
[searchParams],
4546
);
4647

47-
const { controller, policies, origin } = useConnection();
48+
const { policies, origin } = useConnection();
49+
const { controller } = useController();
4850
const [isLoading, setIsLoading] = useState<boolean>(true);
4951

5052
// Handler for calling the callback uri.

packages/keychain/src/components/settings/Delegate.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import { useConnection } from "@/hooks/connection";
44
import { useCallback, useEffect, useState } from "react";
55
import { CallData, num } from "starknet";
66
import { ExecuteCtx } from "@/utils/connection";
7+
import { useController } from "@/hooks/controller";
78

89
export function Delegate({ onBack }: { onBack: () => void }) {
9-
const { controller, context, setContext } = useConnection();
10+
const { context, setContext } = useConnection();
11+
const { controller } = useController();
1012
const [delegateAddress, setDelegateAddress] = useState("");
1113
const [isValid, setIsValid] = useState(true);
1214

0 commit comments

Comments
 (0)