Skip to content

Commit

Permalink
Check session on execute fallback (#1268)
Browse files Browse the repository at this point in the history
  • Loading branch information
tarrencev authored Jan 10, 2025
1 parent 7fc3563 commit 603f720
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 88 deletions.
52 changes: 44 additions & 8 deletions packages/keychain/src/components/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useEffect, useState } from "react";
import { usePostHog } from "posthog-js/react";
import { ResponseCodes } from "@cartridge/controller";
import { useConnection } from "@/hooks/connection";
import { DeployCtx, SignMessageCtx } from "@/utils/connection";
import { DeployCtx, ExecuteCtx, SignMessageCtx } from "@/utils/connection";
import { ConfirmTransaction } from "./transaction/ConfirmTransaction";
import { CreateController, CreateSession, Logout, Upgrade } from "./connect";
import { LoginMode } from "./connect/types";
Expand All @@ -13,9 +13,11 @@ import { PurchaseCredits } from "./funding/PurchaseCredits";
import { Settings } from "./settings";
import { SignMessage } from "./SignMessage";
import { PageLoading } from "./Loading";
import { execute } from "@/utils/connection/execute";

export function Home() {
const { context, controller, error, policies, upgrade } = useConnection();
const { context, setContext, controller, error, policies, upgrade } =
useConnection();
const [hasSessionForPolicies, setHasSessionForPolicies] = useState<
boolean | undefined
>(undefined);
Expand Down Expand Up @@ -60,8 +62,9 @@ export function Home() {
return <CreateController loginMode={LoginMode.Controller} />;
}

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

if (upgrade.available) {
Expand All @@ -87,10 +90,7 @@ export function Home() {
return <></>;
}

if (hasSessionForPolicies === undefined) {
// This is likely never observable in a real application but just in case.
return <PageLoading />;
} else if (hasSessionForPolicies) {
if (hasSessionForPolicies) {
context.resolve({
code: ResponseCodes.SUCCESS,
address: controller.address,
Expand All @@ -113,6 +113,7 @@ export function Home() {
/>
);
}

case "logout": {
posthog?.capture("Call Logout");

Expand All @@ -136,11 +137,46 @@ export function Home() {
/>
);
}

case "execute": {
posthog?.capture("Call Execute");

const ctx = context as ExecuteCtx;
if (!hasSessionForPolicies) {
return (
<CreateSession
isUpdate
policies={policies!}
onConnect={async () => {
const res = await execute({
setContext: (nextCtx) => {
setContext(nextCtx);
},
})(
ctx.transactions,
ctx.abis || [],
ctx.transactionsDetail,
false,
);

setHasSessionForPolicies(true);

if ("transaction_hash" in res) {
// resets execute ui
setContext(undefined);
return ctx.resolve?.({
code: ResponseCodes.SUCCESS,
transaction_hash: res.transaction_hash,
});
}
}}
/>
);
}

return <ConfirmTransaction />;
}

case "deploy": {
posthog?.capture("Call Deploy");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import { useEffect, useMemo, useState } from "react";
import { ResponseCodes, toArray } from "@cartridge/controller";
import { Content, FOOTER_MIN_HEIGHT } from "@/components/layout";
import { TransactionDuoIcon } from "@cartridge/ui-next";
import { useConnection } from "@/hooks/connection";
import { TransactionSummary } from "@/components/transaction/TransactionSummary";
import { ExecuteCtx } from "@/utils/connection";
import { getChecksumAddress, num } from "starknet";
import { num } from "starknet";
import { ExecutionContainer } from "@/components/ExecutionContainer";
import { CreateSession } from "../connect";
import { ParsedSessionPolicies } from "@/hooks/session";

export function ConfirmTransaction() {
const { controller, context, origin, policies, setContext } = useConnection();
const [policiesUpdated, setIsPoliciesUpdated] = useState<boolean>(false);
const [updateSession, setUpdateSession] = useState<boolean>(false);
const { controller, context, origin, setContext } = useConnection();
const ctx = context as ExecuteCtx;
const account = controller;
const transactions = toArray(ctx.transactions);
Expand All @@ -34,63 +29,6 @@ export function ConfirmTransaction() {
setContext(undefined);
};

const callPolicies = useMemo<ParsedSessionPolicies>(() => {
const contracts = new Map();

transactions.forEach((c) => {
const address = getChecksumAddress(c.contractAddress);
if (contracts.has(address)) {
// Extend methods if contract already exists
const existing = contracts.get(address);
existing.methods.push({ entrypoint: c.entrypoint });
} else {
// Add new contract entry
contracts.set(address, { methods: [{ entrypoint: c.entrypoint }] });
}
});

return {
contracts: Object.fromEntries(contracts),
verified: false,
};
}, [ctx.transactions]);

useEffect(() => {
if (policiesUpdated) {
setUpdateSession(false);
return;
}

const entries = Object.entries(callPolicies.contracts || {});
const txnsApproved = entries.every(([target, policy]) => {
const contract = policies?.contracts?.[target];
if (!contract) return false;
return policy.methods.every((method) =>
contract.methods.some((m) => m.entrypoint === method.entrypoint),
);
});

// If calls are approved by dapp specified policies but not stored session
// then prompt user to update session. This also accounts for expired sessions.
if (txnsApproved && account) {
account.isRequestedSession(callPolicies).then((isRequestedSession) => {
setUpdateSession(!isRequestedSession);
});
} else {
setUpdateSession(false);
}
}, [policiesUpdated, policies, account]);

if (updateSession && policies) {
return (
<CreateSession
policies={policies}
isUpdate
onConnect={() => setIsPoliciesUpdated(true)}
/>
);
}

return (
<ExecutionContainer
Icon={TransactionDuoIcon}
Expand Down
2 changes: 0 additions & 2 deletions packages/keychain/src/hooks/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
toArray,
toSessionPolicies,
} from "@cartridge/controller";
import { setIsSignedUp } from "@/utils/cookie";
import {
ConnectionContext,
ConnectionContextValue,
Expand Down Expand Up @@ -97,7 +96,6 @@ export function useConnectionValue() {
}

setControllerRaw(controller);
setIsSignedUp();
}, []);

useEffect(() => {
Expand Down
4 changes: 2 additions & 2 deletions packages/keychain/src/utils/connection/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Controller from "@/utils/controller";
import { connect } from "./connect";
import { execute } from "./execute";
import { estimateDeclareFee, estimateInvokeFee } from "./estimate";
import { probeFactory } from "./probe";
import { probe } from "./probe";
import { signMessageFactory } from "./sign";
import { fetchControllers } from "./fetchControllers";
import { ConnectionCtx } from "./types";
Expand Down Expand Up @@ -41,7 +41,7 @@ export function connectToController<ParentMethods extends object>({
execute: () => execute({ setContext }),
estimateDeclareFee: () => estimateDeclareFee,
estimateInvokeFee: () => estimateInvokeFee,
probe: normalize(probeFactory({ setController, setRpcUrl })),
probe: normalize(probe({ setController, setRpcUrl })),
signMessage: () => signMessageFactory(setContext),
openSettings: () => openSettingsFactory(setContext),
reset: () => () => setContext(undefined),
Expand Down
2 changes: 1 addition & 1 deletion packages/keychain/src/utils/connection/probe.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ProbeReply, ResponseCodes } from "@cartridge/controller";
import Controller from "@/utils/controller";

export function probeFactory({
export function probe({
setController,
setRpcUrl,
}: {
Expand Down
11 changes: 0 additions & 11 deletions packages/keychain/src/utils/cookie.ts

This file was deleted.

0 comments on commit 603f720

Please sign in to comment.