diff --git a/.changeset/tiny-apes-give.md b/.changeset/tiny-apes-give.md
new file mode 100644
index 00000000..bad79c54
--- /dev/null
+++ b/.changeset/tiny-apes-give.md
@@ -0,0 +1,5 @@
+---
+"@starknet-react/core": patch
+---
+
+Fix wallet connection when wallet not authorized
diff --git a/.changeset/tough-timers-rescue.md b/.changeset/tough-timers-rescue.md
new file mode 100644
index 00000000..0172b4c2
--- /dev/null
+++ b/.changeset/tough-timers-rescue.md
@@ -0,0 +1,5 @@
+---
+"@starknet-react/core": patch
+---
+
+Add hook to detect injected connectors
diff --git a/website/app/docs/layout.tsx b/website/app/docs/layout.tsx
index 28ed13b0..476a741e 100644
--- a/website/app/docs/layout.tsx
+++ b/website/app/docs/layout.tsx
@@ -17,4 +17,3 @@ export default function DocLayout({ children }: { children: React.ReactNode }) {
);
}
-
diff --git a/website/app/hooks/[[...slug]]/page.tsx b/website/app/hooks/[[...slug]]/page.tsx
new file mode 100644
index 00000000..bbfdf58b
--- /dev/null
+++ b/website/app/hooks/[[...slug]]/page.tsx
@@ -0,0 +1,58 @@
+import React from "react";
+
+import { notFound, redirect } from "next/navigation";
+
+import { allHooks } from "@/.contentlayer/generated";
+import { Mdx } from "@/components/mdx";
+import { DocContainer } from "@/components/container";
+
+type DocPageProps = {
+ params: {
+ slug: string[];
+ };
+};
+
+async function getDocFromParams({ params }: DocPageProps) {
+ const slug = params.slug?.join("/") || "";
+
+ if (slug === "") {
+ const redirectTo = allHooks[0]?.slugAsParams;
+ return { doc: null, redirectTo };
+ }
+
+ const doc = allHooks.find((doc) => doc.slugAsParams === slug);
+
+ if (!doc) {
+ return { doc: null, redirectTo: null };
+ }
+
+ return { doc, redirectTo: null };
+}
+
+export async function generateStaticParams(): Promise<
+ DocPageProps["params"][]
+> {
+ return allHooks.map((doc) => ({
+ slug: doc.slugAsParams.split("/"),
+ }));
+}
+
+export default async function DocPage({ params }: DocPageProps) {
+ const { doc, redirectTo } = await getDocFromParams({ params });
+
+ if (!doc) {
+ if (redirectTo) {
+ redirect(`/hooks/${redirectTo}`);
+ } else {
+ notFound();
+ }
+ }
+
+ return (
+
+
+
+ );
+}
+
+
diff --git a/website/app/hooks/layout.tsx b/website/app/hooks/layout.tsx
new file mode 100644
index 00000000..32f269c2
--- /dev/null
+++ b/website/app/hooks/layout.tsx
@@ -0,0 +1,19 @@
+import React from "react";
+
+import { Sidebar } from "@/components/sidebar";
+import { ScrollArea } from "@/components/ui/scroll-area";
+import { docsSidebar } from "@/lib/sidebar";
+
+export default function HookLayout({ children }: { children: React.ReactNode }) {
+ return (
+
+ );
+}
+
diff --git a/website/components/starknet/provider.tsx b/website/components/starknet/provider.tsx
index 3ac44e04..95b178c0 100644
--- a/website/components/starknet/provider.tsx
+++ b/website/components/starknet/provider.tsx
@@ -7,8 +7,8 @@ import {
publicProvider,
argent,
braavos,
+ useInjectedConnectors,
} from "@starknet-react/core";
-import { useInjectedConnectors } from "@/../packages/core/dist";
export function StarknetProvider({ children }: { children: React.ReactNode }) {
const chains = [goerli, mainnet];
diff --git a/website/content/docs/getting-started.mdx b/website/content/docs/getting-started.mdx
index 2f1a4561..b146f000 100644
--- a/website/content/docs/getting-started.mdx
+++ b/website/content/docs/getting-started.mdx
@@ -52,6 +52,9 @@ following:
- _connectors_: the wallet connectors supported by your dapp. See
the [wallets](/docs/wallets) page for more information.
+Starknet React provides the `useInjectedConnectors` hook to merge a static list
+of recommended connectors with a dynamic list of injected connectors.
+
```tsx components/starknet-provider.tsx
"use client";
import React from "react";
@@ -62,12 +65,23 @@ import {
publicProvider,
argent,
braavos,
+ useInjectedConnectors,
} from "@starknet-react/core";
export function StarknetProvider({ children }: { children: React.ReactNode }) {
const chains = [goerli];
const providers = [publicProvider()];
- const connectors = [braavos(), argent()];
+ const { connectors } = useInjectedConnectors({
+ // Show these connectors if the user has no connector installed.
+ recommended: [
+ argent(),
+ braavos(),
+ ],
+ // Hide recommended connectors if the user has any connector installed.
+ includeRecommended: "onlyIfNoConnectors",
+ // Randomize the order of the connectors.
+ order: "random"
+ });
return (
+ {children}
+
+ );
+}
+```
+
+## Options
+
+ * `recommended?: Connector[]`
+ - List of recommended connectors.
+
+ * `includeRecommended?: "always" | "onlyIfNoConnectors"`
+ - If `"always"`, the hook always returns the recommended connectors.
+ - If `"onlyIfNoConnectors"`, the recommended connectors are included only if
+ no other connector is installed.
+
+ * `order?: "random" | "alphabetical"`
+ - Control the order in which connectors are returned.
+ - If `"random"`, connectors are shuffled.
+ - If `"alphabetical"`, connectors are alphabetically sorted by their id.
+
+## Returns
+
+ * `connectors: Connector[]`
+ - Contains the list of injected connectors installed by the user.
+ - All connectors are unique and sorted.
diff --git a/website/contentlayer.config.ts b/website/contentlayer.config.ts
index c4d0f149..44c245d9 100644
--- a/website/contentlayer.config.ts
+++ b/website/contentlayer.config.ts
@@ -35,6 +35,23 @@ export const Doc = defineDocumentType(() => ({
},
}));
+export const Hook = defineDocumentType(() => ({
+ name: "Hook",
+ filePathPattern: "hooks/**/*.mdx",
+ contentType: "mdx",
+ computedFields,
+ fields: {
+ title: {
+ required: true,
+ type: "string",
+ },
+ priority: {
+ required: true,
+ type: "number",
+ },
+ },
+}));
+
export const Demo = defineDocumentType(() => ({
name: "Demo",
filePathPattern: "demos/**/*.mdx",
@@ -54,7 +71,7 @@ export const Demo = defineDocumentType(() => ({
export default makeSource({
contentDirPath: "content",
- documentTypes: [Doc, Demo],
+ documentTypes: [Doc, Hook, Demo],
mdx: {
remarkPlugins: [
[
diff --git a/website/lib/sidebar.ts b/website/lib/sidebar.ts
index 50a2ffcf..07bfe1ef 100644
--- a/website/lib/sidebar.ts
+++ b/website/lib/sidebar.ts
@@ -1,8 +1,9 @@
-import { allDemos, allDocs } from "@/.contentlayer/generated";
+import { allDemos, allDocs, allHooks } from "@/.contentlayer/generated";
import type { NavItemWithChildren } from "@/components/sidebar";
const sortedDemos = allDemos.sort((a, b) => b.priority - a.priority);
+const sortedHooks = allHooks.sort((a, b) => b.priority - a.priority);
export const demoSidebar: NavItemWithChildren[] = [
{
@@ -26,4 +27,12 @@ export const docsSidebar: NavItemWithChildren[] = [
items: [],
})),
},
+ {
+ title: "Hooks",
+ items: sortedHooks.map(({ title, slugAsParams }) => ({
+ title,
+ href: `/hooks/${slugAsParams}`,
+ items: [],
+ })),
+ }
];
diff --git a/website/styles/globals.css b/website/styles/globals.css
index b66b0b20..4e547904 100644
--- a/website/styles/globals.css
+++ b/website/styles/globals.css
@@ -90,3 +90,7 @@
@apply leading-6 font-mono;
font-size: 15px;
}
+
+.mdx :where(ul ul, ul ol, ol ul, ol ol) {
+ margin-top: 0;
+}