Skip to content
Merged
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

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import {
ArrowLeftRightIcon,
ChevronRightIcon,
CircleAlertIcon,
ExternalLinkIcon,
} from "lucide-react";
import Link from "next/link";
import type { Project } from "@/api/project/projects";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { CodeServer } from "@/components/ui/code/code.server";
import { UnderlineLink } from "@/components/ui/UnderlineLink";
import { DotNetIcon } from "@/icons/brand-icons/DotNetIcon";
import { GithubIcon } from "@/icons/brand-icons/GithubIcon";
import { ReactIcon } from "@/icons/brand-icons/ReactIcon";
Expand All @@ -25,7 +22,6 @@ import {
type ProjectWalletSummary,
} from "@/lib/server/project-wallet";
import { ClientIDSection } from "./ClientIDSection";
import { IntegrateAPIKeyCodeTabs } from "./IntegrateAPIKeyCodeTabs";
import { ProjectWalletControls } from "./ProjectWalletControls.client";
import { ProjectWalletSetup } from "./ProjectWalletSetup.client";
import { SecretKeySection } from "./SecretKeySection";
Expand All @@ -46,10 +42,7 @@ export async function ProjectFTUX(props: {
wallet={projectWallet}
managementAccessToken={props.managementAccessToken}
/>
<IntegrateAPIKeySection
project={props.project}
teamSlug={props.teamSlug}
/>
<IntegrateAPIKeySection project={props.project} />
<ProductsSection
projectSlug={props.project.slug}
teamSlug={props.teamSlug}
Expand Down Expand Up @@ -83,8 +76,7 @@ export function ProjectWalletSection(props: {
Project Wallet
</p>
<p className="text-muted-foreground text-sm">
Default managed server wallet for this project. Use it for
deployments, payments, and API integrations.
Use it for deployments, payments, and API integrations.
</p>
</div>
</div>
Expand Down Expand Up @@ -121,13 +113,7 @@ export function ProjectWalletSection(props: {

// Integrate API key section ------------------------------------------------------------

function IntegrateAPIKeySection({
project,
teamSlug,
}: {
project: Project;
teamSlug: string;
}) {
function IntegrateAPIKeySection({ project }: { project: Project }) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add explicit return type.

Per coding guidelines, TypeScript functions should have explicit return types.

As per coding guidelines.

Apply this diff:

-function IntegrateAPIKeySection({ project }: { project: Project }) {
+function IntegrateAPIKeySection({ project }: { project: Project }): React.JSX.Element {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function IntegrateAPIKeySection({ project }: { project: Project }) {
function IntegrateAPIKeySection({ project }: { project: Project }): React.JSX.Element {
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectFTUX/ProjectFTUX.tsx
around line 116, the function declaration for IntegrateAPIKeySection lacks an
explicit TypeScript return type; update the function signature to include an
explicit React return type (e.g., : JSX.Element or : React.ReactElement) so the
component's return type is explicit and matches project coding guidelines, and
ensure any necessary React types are imported if not already.

const secretKeyMasked = project.secretKeys[0]?.masked;
const clientId = project.publishableKey;

Expand All @@ -149,194 +135,38 @@ function IntegrateAPIKeySection({
</div>

<div className="h-5" />
<IntegrationCodeExamples project={project} teamSlug={teamSlug} />
</div>
</section>
);
}

function IntegrationCodeExamples(props: {
project: Project;
teamSlug: string;
}) {
return (
<IntegrateAPIKeyCodeTabs
tabs={{
dotnet: (
<div className="flex flex-col gap-3">
<CodeServer
className="bg-background"
code={dotNotCodeExample(props.project)}
lang="csharp"
/>
<Alert className="bg-background" variant="info">
<CircleAlertIcon className="size-5" />
<AlertTitle>
Configure your app's bundle ID in "Allowed Bundle IDs" in
Project
</AlertTitle>
<AlertDescription className="leading-loose">
Go to{" "}
<UnderlineLink
href={`/team/${props.teamSlug}/${props.project.slug}/settings`}
target="_blank"
>
Project settings
</UnderlineLink>{" "}
and add your app's bundle ID to the "Allowed Bundle IDs" list.
</AlertDescription>
</Alert>
</div>
),
react: (
<CodeServer
className="bg-background"
code={reactCodeExample(props.project)}
lang="ts"
/>
),
"react-native": (
<CodeServer
className="bg-background"
code={reactCodeExample(props.project)}
lang="ts"
/>
),
ts: (
<div className="flex flex-col gap-3">
<p className="text-muted-foreground text-sm">
Run this command in your terminal to send a test transaction using
your Project Wallet.
</p>
<CodeServer
className="bg-background"
code={typescriptCodeExample(props.project)}
lang="ts"
/>
),
unity: (
<Alert className="bg-background" variant="info">
<CircleAlertIcon className="size-5" />
<AlertTitle>
Configure Client ID in Thirdweb Manager prefab
</AlertTitle>
<AlertDescription className="leading-loose">
Configure "Client ID" and "Bundle ID" in{" "}
<UnderlineLink
href="https://portal.thirdweb.com/unity/v5/thirdwebmanager"
rel="noopener noreferrer"
target="_blank"
>
Thirdweb Manager prefab
</UnderlineLink>
<span className="block text-sm">
Make sure to configure your app's bundle ID in "Allowed Bundle
IDs" in{" "}
<UnderlineLink
href={`/team/${props.teamSlug}/${props.project.slug}/settings`}
rel="noopener noreferrer"
target="_blank"
>
Project settings
</UnderlineLink>
</span>
</AlertDescription>
</Alert>
),
unreal: (
<Alert className="bg-background" variant="info">
<CircleAlertIcon className="size-5" />
<AlertTitle>
Configure Client ID in Thirdweb Unreal Plugin{" "}
</AlertTitle>
<AlertDescription className="leading-loose">
Configure "Client ID" and "Bundle ID" in{" "}
<UnderlineLink
href="https://portal.thirdweb.com/unreal-engine/getting-started"
rel="noopener noreferrer"
target="_blank"
>
thirdweb plugin settings
</UnderlineLink>
<span className="block text-sm">
Make sure to configure your app's bundle ID in "Allowed Bundle
IDs" in{" "}
<UnderlineLink
href={`/team/${props.teamSlug}/${props.project.slug}/settings`}
rel="noopener noreferrer"
target="_blank"
>
Project settings
</UnderlineLink>
</span>
</AlertDescription>
</Alert>
),
api: (
<CodeServer
className="bg-background"
code={apiCodeExample(props.project)}
lang="javascript"
/>
),
curl: (
<CodeServer
className="bg-background"
code={curlCodeExample(props.project)}
code={curlCodeExample(project)}
lang="bash"
/>
),
}}
/>
</div>
</div>
</section>
);
}

const typescriptCodeExample = (project: Project) => `\
import { createThirdwebClient } from "thirdweb";

const client = createThirdwebClient({
// use clientId for client side usage
clientId: "${project.publishableKey}",
// use secretKey for server side usage
secretKey: "${project.secretKeys[0]?.masked}", // replace this with full secret key
});`;

const reactCodeExample = (project: Project) => `\
import { createThirdwebClient } from "thirdweb";

const client = createThirdwebClient({
clientId: "${project.publishableKey}",
});`;

const dotNotCodeExample = (project: Project) => `\
using Thirdweb;

// For web applications
var client = ThirdwebClient.Create(clientId: "${project.publishableKey}");

// For native applications - Replace "yourBundleId" with your app's bundle ID
var client = ThirdwebClient.Create(clientId: "${project.publishableKey}", bundleId: "yourBundleId");

// For backend applications (Note: below shown secret key is not the full secret key)
var client = ThirdwebClient.Create(secretKey: "${project.secretKeys[0]?.masked}");`;

const apiCodeExample = (project: Project): string => `\
// Server-side only: replace with your full secret key. Never expose in browser code.
fetch('https://api.thirdweb.com/v1/wallets/server', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-secret-key': '${project.secretKeys[0]?.masked ?? "<YOUR_SECRET_KEY>"}'
},
body: JSON.stringify({
identifier: 'treasury-wallet-123'
})
});`;

const curlCodeExample = (project: Project): string => `\
// Server-side only: replace with your full secret key. Never expose in browser code.
curl https://api.thirdweb.com/v1/wallets/server \\
curl https://api.thirdweb.com/v1/transactions \\
--request POST \\
--header 'Content-Type: application/json' \\
--header 'x-secret-key: ${project.secretKeys[0]?.masked ?? "<YOUR_SECRET_KEY>"}' \\
--data '{
"identifier": "treasury-wallet-123"
}'`;
"chainId": 421614,
"transactions": [
{
"data": "0x",
"to": "vitalik.eth",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Consider using a standard address instead of an ENS name.

The "to" field uses "vitalik.eth", an ENS name that may not resolve on chainId 421614 (Arbitrum Sepolia testnet). Consider using a standard Ethereum address (e.g., 0x0000000000000000000000000000000000000000 or a well-known address) to ensure the example works reliably across all environments.

🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectFTUX/ProjectFTUX.tsx
around line 163, the example transaction "to" field uses the ENS name
"vitalik.eth" which may not resolve on chainId 421614; replace that ENS value
with a standard hex Ethereum address (for example a zero address or any
well-known checksummed address) so the example works reliably across
environments, ensuring the string is a valid 0x-prefixed 40-hex-character
address.

"value": "0"
}
]
}'
`;

// products section ------------------------------------------------------------

function ProductsSection(props: { teamSlug: string; projectSlug: string }) {
Expand Down
Loading