Skip to content
Open
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
9 changes: 0 additions & 9 deletions examples/next/src/components/providers/StarknetProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,6 @@ const controller = new ControllerConnector({
// However, if you want to use custom RPC URLs, you can still specify them:
chains: controllerConnectorChains,
url: keychainUrl,
signupOptions: [
"google",
"webauthn",
"discord",
"walletconnect",
"metamask",
"rabby",
"password",
],
slot: "arcade-pistols",
namespace: "pistols",
preset: "pistols",
Expand Down
33 changes: 25 additions & 8 deletions packages/controller/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
ExternalWallet,
ExternalWalletResponse,
ExternalWalletType,
externalWalletTypes,
} from "./wallets/types";

export type KeychainSession = {
Expand All @@ -30,15 +31,31 @@ export type KeychainSession = {
};
};

export type AuthOption =
| "google"
| "webauthn"
| "discord"
| "walletconnect"
| "password"
| ExternalWalletType;
export const EMBEDDED_WALLETS = [
"sms",
"google",
"webauthn",
"discord",
"walletconnect",
"password",
] as const;

export type AuthOptions = Omit<AuthOption, "phantom" | "argent">[];
export type EmbeddedWallet = (typeof EMBEDDED_WALLETS)[number];

export const ALL_AUTH_OPTIONS = [
...EMBEDDED_WALLETS,
...externalWalletTypes,
] as const;

export type AuthOption = (typeof ALL_AUTH_OPTIONS)[number];

export const VALID_AUTH_OPTIONS = [
...ALL_AUTH_OPTIONS.filter(
(x) => x !== "phantom" && x !== "argent" && x !== "braavos" && x !== "base",
),
] as const;

export type AuthOptions = (typeof VALID_AUTH_OPTIONS)[number][];

export enum ResponseCodes {
SUCCESS = "SUCCESS",
Expand Down
17 changes: 10 additions & 7 deletions packages/controller/src/wallets/types.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
export type ExternalWalletType =
| "argent"
| "braavos"
| "metamask"
| "phantom"
| "rabby"
| "base";
export const externalWalletTypes = [
"argent",
"braavos",
"metamask",
"phantom",
"rabby",
"base",
] as const;
export type ExternalWalletType = (typeof externalWalletTypes)[number];

export type ExternalPlatform =
| "starknet"
| "ethereum"
Expand Down
14 changes: 7 additions & 7 deletions packages/keychain/.storybook/provider.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import React, { PropsWithChildren } from "react";
import { QueryClient, QueryClientProvider } from "react-query";
import { mainnet } from "@starknet-react/chains";
import {
StarknetConfig,
cartridge,
publicProvider,
} from "@starknet-react/core";
import React, { PropsWithChildren } from "react";
import { QueryClient, QueryClientProvider } from "react-query";
import { BrowserRouter } from "react-router-dom";
import { ConnectionContext } from "../src/components/provider/connection";
import { PostHogProvider } from "../src/components/provider/posthog";
import { TokensProvider } from "../src/components/provider/tokens";
import { UIProvider } from "../src/components/provider/ui";
import { NavigationProvider } from "../src/context/navigation";
import { FeatureProvider } from "../src/hooks/features";
import { WalletsProvider } from "../src/hooks/wallets";
import {
MockUpgradeProvider,
StoryParameters,
useMockedConnection,
} from "./mock";
import { TokensProvider } from "../src/components/provider/tokens";
import { PostHogProvider } from "../src/components/provider/posthog";
import { WalletsProvider } from "../src/hooks/wallets";
import { FeatureProvider } from "../src/hooks/features";
import { NavigationProvider } from "../src/context/navigation";

export function Provider({
children,
Expand Down
2 changes: 2 additions & 0 deletions packages/keychain/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
"history": "^5.3.0",
"inapp-spy": "4.2.1",
"jwt-decode": "^4.0.0",
"libphonenumber-js": "^1.12.10",
"lodash": "catalog:",
"p-throttle": "^6.2.0",
"posthog-js-lite": "3.2.1",
"qrcode.react": "catalog:",
Expand Down
15 changes: 11 additions & 4 deletions packages/keychain/src/components/connect/buttons/signup-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import {
DiscordColorIcon,
GoogleColorIcon,
IconProps,
LockIcon,
MetaMaskColorIcon,
MobileIcon,
PasskeyIcon,
PhantomColorIcon,
RabbyColorIcon,
Spinner,
WalletConnectColorIcon,
LockIcon,
} from "@cartridge/ui";
import { cn } from "@cartridge/ui/utils";

Expand All @@ -24,7 +25,8 @@ const OPTIONS: Partial<
string,
{
variant: "primary" | "secondary";
Icon: React.ComponentType<IconProps>;
Icon?: React.ComponentType<IconProps>;
icon?: React.ReactNode;
label: string;
className?: string;
}
Expand Down Expand Up @@ -76,6 +78,11 @@ const OPTIONS: Partial<
Icon: LockIcon,
label: AUTH_METHODS_LABELS.password,
},
sms: {
variant: "secondary",
icon: <MobileIcon size="sm" variant="solid" />,
label: AUTH_METHODS_LABELS.sms,
},
};

export function SignupButton({ authMethod, ...props }: SignupButtonProps) {
Expand All @@ -88,7 +95,7 @@ export function SignupButton({ authMethod, ...props }: SignupButtonProps) {
return null;
}

const { Icon, label, ...restOptionProps } = option;
const { Icon, icon, label, ...restOptionProps } = option;

return (
<Button
Expand All @@ -98,7 +105,7 @@ export function SignupButton({ authMethod, ...props }: SignupButtonProps) {
isLoading={false}
disabled={isLoading || disabled}
>
{isLoading ? <Spinner size="sm" /> : <Icon size="sm" />}
{isLoading ? <Spinner size="sm" /> : Icon ? <Icon size="sm" /> : icon}
{label}
</Button>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { usePostHog } from "@/components/provider/posthog";
import { useControllerTheme } from "@/hooks/connection";
import { useDebounce } from "@/hooks/debounce";
import { allUseSameAuth } from "@/utils/controller";
import { AuthOption } from "@cartridge/controller";
import { AuthOption, AuthOptions } from "@cartridge/controller";
import {
CartridgeLogo,
ControllerIcon,
Expand Down Expand Up @@ -46,7 +46,7 @@ interface CreateControllerViewProps {
waitingForConfirmation: boolean;
changeWallet: boolean;
setChangeWallet: (value: boolean) => void;
authOptions: AuthOption[];
authOptions: AuthOptions;
authMethod: AuthOption | undefined;
}

Expand Down Expand Up @@ -253,7 +253,7 @@ export function CreateController({
waitingForConfirmation,
changeWallet,
setChangeWallet,
signupOptions,
supportedSignupOptions,
authMethod,
} = useCreateController({
isSlot,
Expand Down Expand Up @@ -285,14 +285,14 @@ export function CreateController({
if (
authenticationMode === undefined &&
!accountExists &&
signupOptions.length > 1
supportedSignupOptions.length > 1
) {
setAuthenticationStep(AuthenticationStep.ChooseMethod);
return;
}
const authenticationMethod =
signupOptions.length === 1 && !accountExists
? signupOptions[0]
supportedSignupOptions.length === 1 && !accountExists
? supportedSignupOptions[0]
: validation.signers &&
(validation.signers.length == 1 ||
allUseSameAuth(validation.signers))
Expand Down Expand Up @@ -321,7 +321,7 @@ export function CreateController({
validation.status,
validation.signers,
setAuthenticationStep,
signupOptions,
supportedSignupOptions,
],
);

Expand Down Expand Up @@ -384,7 +384,7 @@ export function CreateController({
waitingForConfirmation={waitingForConfirmation}
changeWallet={changeWallet}
setChangeWallet={setChangeWallet}
authOptions={signupOptions}
authOptions={supportedSignupOptions}
authMethod={authMethod}
/>
{overlay}
Expand Down
41 changes: 41 additions & 0 deletions packages/keychain/src/components/connect/create/sms/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { SmsWallet } from "@/wallets/social/sms-wallet";
import { AuthOption, WalletAdapter } from "@cartridge/controller";
import { useCallback } from "react";

export const useSmsAuthentication = () => {
const signup = useCallback(
async (
connectType: "signup" | "login" | "add-signer",
username: string,
) => {
const smsWallet = new SmsWallet(username, connectType);

const response = await smsWallet.connect();

if (!response.success || !response.account) {
throw new Error(response.error);
}

if (!window.keychain_wallets) {
throw new Error("No keychain_wallets found");
}

window.keychain_wallets.addEmbeddedWallet(
response.account,
smsWallet as unknown as WalletAdapter,
);

return {
address: response.account,
signer: { eip191: { address: response.account } },
type: "sms" as AuthOption,
};
},
[],
);

return {
signup: (username: string) => signup("signup", username),
login: (username: string) => signup("login", username),
};
};
Loading
Loading