diff --git a/packages/keychain/src/components/app.tsx b/packages/keychain/src/components/app.tsx
index 0f580bbef..80a27a623 100644
--- a/packages/keychain/src/components/app.tsx
+++ b/packages/keychain/src/components/app.tsx
@@ -7,6 +7,7 @@ import { Success } from "./success";
import { Pending } from "./pending";
import { Consent, Slot } from "./slot";
import { OcclusionDetector } from "./OcclusionDetector";
+import { Fund } from "./slot/fund";
export function App() {
return (
@@ -19,6 +20,7 @@ export function App() {
} />
}>
} />
+ } />
} />
} />
diff --git a/packages/keychain/src/components/funding/Balance.tsx b/packages/keychain/src/components/funding/Balance.tsx
index 341ee94fb..491b87551 100644
--- a/packages/keychain/src/components/funding/Balance.tsx
+++ b/packages/keychain/src/components/funding/Balance.tsx
@@ -10,26 +10,34 @@ import { TokenPair } from "@cartridge/utils/api/cartridge";
import { formatEther } from "viem";
import {
ETH_CONTRACT_ADDRESS,
+ isIframe,
useCountervalue,
useCreditBalance,
useERC20Balance,
} from "@cartridge/utils";
import { useController } from "@/hooks/controller";
+import { useEffect, useState } from "react";
+import Controller from "@/utils/controller";
+
+export type BalanceType = "credits" | "eth" | "strk";
type BalanceProps = {
- showBalances: ("credits" | "eth" | "strk")[];
+ showBalances: BalanceType[];
};
export function Balance({ showBalances }: BalanceProps) {
+ const [username, setUsername] = useState();
+ const [address, setAddress] = useState();
const { controller } = useController();
const { balance: creditBalance } = useCreditBalance({
- username: controller?.username(),
+ username: username,
interval: 3000,
});
+
const {
data: [eth],
} = useERC20Balance({
- address: controller?.address,
+ address: address,
contractAddress: ETH_CONTRACT_ADDRESS,
provider: controller,
interval: 3000,
@@ -43,6 +51,17 @@ export function Balance({ showBalances }: BalanceProps) {
{ enabled: !!eth },
);
+ useEffect(() => {
+ const activeController = !isIframe()
+ ? Controller.fromStore(import.meta.env.VITE_ORIGIN!)
+ : controller;
+
+ if (activeController) {
+ setUsername(activeController.username());
+ setAddress(activeController.address);
+ }
+ }, [controller]);
+
return (
diff --git a/packages/keychain/src/components/funding/PurchaseCredits.tsx b/packages/keychain/src/components/funding/PurchaseCredits.tsx
index 4cf267d82..52ad77c22 100644
--- a/packages/keychain/src/components/funding/PurchaseCredits.tsx
+++ b/packages/keychain/src/components/funding/PurchaseCredits.tsx
@@ -82,24 +82,6 @@ export function PurchaseCredits({ onBack }: PurchaseCreditsProps) {
},
} as Appearance;
- // For when we need to support Payment Links
- // useStripePaymentQuery(
- // { referenceId },
- // {
- // enabled: !!referenceId && !error,
- // refetchInterval: REFETCH_INTERVAL,
- // retry: MAX_RETRIES,
- // onSuccess: () => setState(PurchaseState.SUCCESS),
- // onError: () => {
- // setError(
- // new Error(
- // `Payment not received. Please try again. Reference ID: ${referenceId}`,
- // ),
- // );
- // },
- // },
- // );
-
if (state === PurchaseState.STRIPE_CHECKOUT) {
return (
diff --git a/packages/keychain/src/components/funding/index.tsx b/packages/keychain/src/components/funding/index.tsx
index 582ed3c26..e401fcb9f 100644
--- a/packages/keychain/src/components/funding/index.tsx
+++ b/packages/keychain/src/components/funding/index.tsx
@@ -10,7 +10,7 @@ import {
} from "@cartridge/ui-next";
import { DepositEth } from "./DepositEth";
import { PurchaseCredits } from "./PurchaseCredits";
-import { Balance } from "./Balance";
+import { Balance, BalanceType } from "./Balance";
const enum FundingState {
SHOW_OPTIONS,
@@ -19,15 +19,20 @@ const enum FundingState {
}
export type FundingProps = {
- title?: React.ReactElement;
+ title?: React.ReactElement | string;
+ creditsOnly?: boolean;
onComplete?: (deployHash?: string) => void;
};
-export function Funding({ onComplete, title }: FundingProps) {
+export function Funding({ title, creditsOnly, onComplete }: FundingProps) {
const { controller } = useConnection();
const [state, setState] = useState(FundingState.SHOW_OPTIONS);
+ const showBalances: BalanceType[] = creditsOnly
+ ? ["credits"]
+ : ["credits", "eth"];
const showCredits =
- typeof document !== "undefined" && document.cookie.includes("credits=");
+ (typeof document !== "undefined" && document.cookie.includes("credits=")) ||
+ creditsOnly;
if (state === FundingState.FUND_ETH) {
return (
@@ -49,9 +54,10 @@ export function Funding({ onComplete, title }: FundingProps) {
title={title || (controller ? `Fund ${controller.username()}` : "")}
description={controller && }
icon={}
+ hideNetwork
>
-
+
);
diff --git a/packages/keychain/src/components/slot/consent.tsx b/packages/keychain/src/components/slot/consent.tsx
index 29bc8b803..14194e1a8 100644
--- a/packages/keychain/src/components/slot/consent.tsx
+++ b/packages/keychain/src/components/slot/consent.tsx
@@ -2,10 +2,11 @@ import Controller from "@/utils/controller";
import { Button } from "@cartridge/ui-next";
import { Container, Footer } from "@/components/layout";
import { useCallback, useEffect } from "react";
-import { useNavigate, useSearchParams } from "react-router-dom";
+import { useLocation, useNavigate, useSearchParams } from "react-router-dom";
export function Consent() {
const navigate = useNavigate();
+ const { pathname } = useLocation();
const [searchParams] = useSearchParams();
const callback_uri = searchParams.get("callback_uri")!;
@@ -25,9 +26,18 @@ export function Consent() {
useEffect(() => {
if (!Controller.fromStore(import.meta.env.VITE_ORIGIN!)) {
- navigate("/slot", { replace: true });
+ navigate(
+ `/slot?returnTo=${encodeURIComponent(pathname)}${
+ callback_uri
+ ? `&callback_uri=${encodeURIComponent(callback_uri)}`
+ : ""
+ }`,
+ {
+ replace: true,
+ },
+ );
}
- }, [navigate]);
+ }, [navigate, callback_uri, pathname]);
return (
{
+ if (!Controller.fromStore(import.meta.env.VITE_ORIGIN!)) {
+ navigate(`/slot?returnTo=${encodeURIComponent(pathname)}`, {
+ replace: true,
+ });
+ }
+ }, [navigate, pathname]);
+
+ return ;
+}
diff --git a/packages/keychain/src/components/slot/index.tsx b/packages/keychain/src/components/slot/index.tsx
index 84da58f69..afcb117bd 100644
--- a/packages/keychain/src/components/slot/index.tsx
+++ b/packages/keychain/src/components/slot/index.tsx
@@ -23,6 +23,7 @@ export function Slot() {
case "/slot/auth/failure":
return ;
case "/slot/consent":
+ case "/slot/fund":
return ;
default:
return ;
@@ -37,13 +38,17 @@ function Auth() {
useEffect(() => {
if (user && controller) {
- const query = Array.from(searchParams.entries()).reduce(
- (prev, [key, val], i) =>
- i === 0 ? `?${key}=${val}` : `${prev}&${key}=${val}`,
- "",
- );
+ const returnTo = searchParams.get("returnTo");
+ const otherParams = Array.from(searchParams.entries())
+ .filter(([key]) => key !== "returnTo")
+ .reduce(
+ (prev, [key, val], i) =>
+ i === 0 ? `?${key}=${val}` : `${prev}&${key}=${val}`,
+ "",
+ );
- navigate(`/slot/consent${query}`, { replace: true });
+ const target = returnTo ? `${returnTo}${otherParams}` : "/slot";
+ navigate(target, { replace: true });
}
}, [user, controller, navigate, searchParams]);