Compare commits
22
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66b9bf3c6b | ||
|
|
cf22c23b45 | ||
|
|
170b020e17 | ||
|
|
8260af3a92 | ||
|
|
b9154cc9e7 | ||
|
|
08955f1588 | ||
|
|
756295241a | ||
|
|
249679481e | ||
|
|
a491de4d7c | ||
|
|
898efc56a9 | ||
|
|
c0e7ae95de | ||
|
|
1e8190a1f9 | ||
|
|
aac187a76c | ||
|
|
03390c1e25 | ||
|
|
8d3b9c6a33 | ||
|
|
ddef88866f | ||
|
|
8133fab9e4 | ||
|
|
37414eb54a | ||
|
|
22bf68a6f0 | ||
|
|
68dd4dc17e | ||
|
|
ecf6dbf2aa | ||
|
|
01daaceb21 |
@@ -661,7 +661,7 @@ export const CodeOverview: React.FC<CodeOverviewProps> = ({
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Connect SDK
|
||||
thirdweb SDK
|
||||
</UnderlineLink>{" "}
|
||||
in your applications. This will ensure account contracts are
|
||||
deployed for your users only when they need it.
|
||||
|
||||
@@ -90,144 +90,6 @@ const MARKETS = {
|
||||
name: "Marketplace",
|
||||
} satisfies ExploreCategory;
|
||||
|
||||
const MODULAR_CONTRACTS = {
|
||||
contracts: [
|
||||
// erc721 drop
|
||||
[
|
||||
"thirdweb.eth/ERC721CoreInitializable",
|
||||
[
|
||||
"deployer.thirdweb.eth/ClaimableERC721",
|
||||
"deployer.thirdweb.eth/BatchMetadataERC721",
|
||||
"deployer.thirdweb.eth/RoyaltyERC721",
|
||||
],
|
||||
{
|
||||
description: "ERC721 NFTs that anyone can mint.",
|
||||
title: "Modular NFT Drop",
|
||||
},
|
||||
],
|
||||
// erc721 token
|
||||
[
|
||||
"thirdweb.eth/ERC721CoreInitializable",
|
||||
[
|
||||
"deployer.thirdweb.eth/MintableERC721",
|
||||
"deployer.thirdweb.eth/BatchMetadataERC721",
|
||||
"deployer.thirdweb.eth/TransferableERC721",
|
||||
],
|
||||
{
|
||||
description: "ERC721 NFTs that only owners can mint.",
|
||||
title: "Modular NFT Collection",
|
||||
},
|
||||
],
|
||||
// open edition 721
|
||||
[
|
||||
"thirdweb.eth/ERC721CoreInitializable",
|
||||
[
|
||||
"deployer.thirdweb.eth/ClaimableERC721",
|
||||
"deployer.thirdweb.eth/OpenEditionMetadataERC721",
|
||||
"deployer.thirdweb.eth/RoyaltyERC721",
|
||||
],
|
||||
{
|
||||
description: "ERC721 NFTs with identical metadata.",
|
||||
title: "Modular Open Edition",
|
||||
},
|
||||
],
|
||||
// erc1155 drop
|
||||
[
|
||||
"thirdweb.eth/ERC1155CoreInitializable",
|
||||
[
|
||||
"deployer.thirdweb.eth/ClaimableERC1155",
|
||||
"deployer.thirdweb.eth/BatchMetadataERC1155",
|
||||
"deployer.thirdweb.eth/RoyaltyERC1155",
|
||||
"deployer.thirdweb.eth/SequentialTokenIdERC1155",
|
||||
],
|
||||
{
|
||||
description: "ERC1155 NFTs that others can mint.",
|
||||
title: "Modular Edition Drop",
|
||||
},
|
||||
],
|
||||
// erc1155 token
|
||||
[
|
||||
"thirdweb.eth/ERC1155CoreInitializable",
|
||||
[
|
||||
"deployer.thirdweb.eth/MintableERC1155",
|
||||
"deployer.thirdweb.eth/BatchMetadataERC1155",
|
||||
"deployer.thirdweb.eth/TransferableERC1155",
|
||||
"deployer.thirdweb.eth/SequentialTokenIdERC1155",
|
||||
],
|
||||
{
|
||||
description: "ERC1155 NFTs that only owners can mint.",
|
||||
title: "Modular Edition",
|
||||
},
|
||||
],
|
||||
// erc20 drop
|
||||
[
|
||||
"thirdweb.eth/ERC20CoreInitializable",
|
||||
[
|
||||
"deployer.thirdweb.eth/ClaimableERC20",
|
||||
"deployer.thirdweb.eth/TransferableERC20",
|
||||
],
|
||||
{
|
||||
description: "ERC20 Tokens that others can mint.",
|
||||
title: "Modular Token Drop",
|
||||
},
|
||||
],
|
||||
// erc20 token
|
||||
[
|
||||
"thirdweb.eth/ERC20CoreInitializable",
|
||||
[
|
||||
"deployer.thirdweb.eth/MintableERC20",
|
||||
"deployer.thirdweb.eth/TransferableERC20",
|
||||
],
|
||||
{
|
||||
description: "ERC20 Tokens that only owners can mint.",
|
||||
title: "Modular Token",
|
||||
},
|
||||
],
|
||||
],
|
||||
description:
|
||||
"Collection of highly customizable and upgradeable smart contracts built with the modular contracts framework.",
|
||||
displayName: "Modular Contracts",
|
||||
id: "modular-contracts",
|
||||
name: "modular",
|
||||
} satisfies ExploreCategory;
|
||||
|
||||
const SUPERCHAIN = {
|
||||
contracts: [
|
||||
// erc20 token + superchain
|
||||
[
|
||||
"thirdweb.eth/ERC20CoreInitializable",
|
||||
[
|
||||
"deployer.thirdweb.eth/MintableERC20",
|
||||
"deployer.thirdweb.eth/TransferableERC20",
|
||||
"deployer.thirdweb.eth/SuperChainInterop",
|
||||
],
|
||||
{
|
||||
description: "ERC20 Tokens that only owners can mint.",
|
||||
title: "Modular Superchain Token",
|
||||
},
|
||||
],
|
||||
// erc20 drop + superchain
|
||||
[
|
||||
"thirdweb.eth/ERC20CoreInitializable",
|
||||
[
|
||||
"deployer.thirdweb.eth/ClaimableERC20",
|
||||
"deployer.thirdweb.eth/TransferableERC20",
|
||||
"deployer.thirdweb.eth/SuperChainInterop",
|
||||
],
|
||||
{
|
||||
description: "ERC20 Tokens that others can mint.",
|
||||
title: "Modular Superchain Token Drop",
|
||||
},
|
||||
],
|
||||
],
|
||||
description: "Modular contracts with OP Superchain support",
|
||||
displayName: "Modular Superchain Contracts",
|
||||
id: "modular-superchain-contracts",
|
||||
isBeta: true,
|
||||
name: "Modular Superchain Contracts",
|
||||
showInExplore: true,
|
||||
} satisfies ExploreCategory;
|
||||
|
||||
const AIRDROP = {
|
||||
contracts: ["thirdweb.eth/Airdrop"],
|
||||
description:
|
||||
@@ -313,12 +175,26 @@ const SMART_WALLET = {
|
||||
showInExplore: true,
|
||||
} satisfies ExploreCategory;
|
||||
|
||||
const STYLUS = {
|
||||
contracts: [
|
||||
"0x6453a486d52e0EB6E79Ec4491038E2522a926936/StylusAirdropERC1155",
|
||||
"0x6453a486d52e0EB6E79Ec4491038E2522a926936/StylusAirdropERC721",
|
||||
"0x6453a486d52e0EB6E79Ec4491038E2522a926936/StylusAirdropERC20",
|
||||
],
|
||||
description:
|
||||
"Airdrop your NFTs or tokens to a large number of recipients. Built with Arbitrum Stylus.",
|
||||
displayName: "Arbitrum Stylus Contracts",
|
||||
id: "stylus",
|
||||
name: "Stylus",
|
||||
showInExplore: true,
|
||||
isBeta: true,
|
||||
} satisfies ExploreCategory;
|
||||
|
||||
const CATEGORIES: Record<string, ExploreCategory> = {
|
||||
[POPULAR.id]: POPULAR,
|
||||
[MODULAR_CONTRACTS.id]: MODULAR_CONTRACTS,
|
||||
[SUPERCHAIN.id]: SUPERCHAIN,
|
||||
[NFTS.id]: NFTS,
|
||||
[MARKETS.id]: MARKETS,
|
||||
[STYLUS.id]: STYLUS,
|
||||
[DROPS.id]: DROPS,
|
||||
[SMART_WALLET.id]: SMART_WALLET,
|
||||
[AIRDROP.id]: AIRDROP,
|
||||
|
||||
+1
-1
@@ -308,7 +308,7 @@ ${Object.keys(populatedTransaction)
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Connect SDK example
|
||||
TypeScript SDK example
|
||||
</a>
|
||||
<CodeClient code={state.codeExample} lang="ts" />
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ const PROBLEM_AREAS: ProblemAreaItem[] = [
|
||||
<DescriptionInputWrapper />
|
||||
</>
|
||||
),
|
||||
label: "Connect SDKs",
|
||||
label: "thirdweb SDKs",
|
||||
},
|
||||
{
|
||||
component: (
|
||||
|
||||
+1
-1
@@ -488,7 +488,7 @@ export function TransactionCharts(props: {
|
||||
autoUpdate: false,
|
||||
instanceUrl: props.instanceUrl,
|
||||
queryParams: {
|
||||
limit: 10000,
|
||||
limit: 2000,
|
||||
page: 1,
|
||||
},
|
||||
});
|
||||
|
||||
+1
@@ -55,6 +55,7 @@ export function AdvancedSearchInput(props: {
|
||||
<SelectItem value="phone">Phone</SelectItem>
|
||||
<SelectItem value="id">ID</SelectItem>
|
||||
<SelectItem value="address">Address</SelectItem>
|
||||
<SelectItem value="externalWallet">External Wallet</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
|
||||
+28
@@ -52,6 +52,11 @@ export function SearchResults(props: {
|
||||
const email = mainDetail?.email as string | undefined;
|
||||
const phone = mainDetail?.phone as string | undefined;
|
||||
|
||||
// Get external wallet addresses from linkedAccounts where type is 'siwe'
|
||||
const externalWalletAccounts =
|
||||
user.linkedAccounts?.filter((account) => account.type === "siwe") ||
|
||||
[];
|
||||
|
||||
return (
|
||||
<Card key={user.id}>
|
||||
<CardHeader>
|
||||
@@ -96,6 +101,29 @@ export function SearchResults(props: {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{externalWalletAccounts.length > 0 && (
|
||||
<div className="col-span-full">
|
||||
<p className="text-sm font-medium text-muted-foreground">
|
||||
External Wallets
|
||||
</p>
|
||||
<div className="space-y-1">
|
||||
{externalWalletAccounts.map((account, index) => {
|
||||
const address = account.details?.address as
|
||||
| string
|
||||
| undefined;
|
||||
return address ? (
|
||||
<div key={`${user.id}-external-${index}`}>
|
||||
<WalletAddress
|
||||
address={address}
|
||||
client={props.client}
|
||||
/>
|
||||
</div>
|
||||
) : null;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{createdAt && (
|
||||
<div>
|
||||
<p className="text-sm font-medium text-muted-foreground">
|
||||
|
||||
+41
@@ -36,6 +36,10 @@ const getUserIdentifier = (accounts: WalletUser["linkedAccounts"]) => {
|
||||
);
|
||||
};
|
||||
|
||||
const getExternalWallets = (accounts: WalletUser["linkedAccounts"]) => {
|
||||
return accounts?.filter((account) => account.type === "siwe") || [];
|
||||
};
|
||||
|
||||
const columnHelper = createColumnHelper<WalletUser>();
|
||||
|
||||
export function InAppWalletUsersPageContent(
|
||||
@@ -69,6 +73,36 @@ export function InAppWalletUsersPageContent(
|
||||
header: "Address",
|
||||
id: "address",
|
||||
}),
|
||||
columnHelper.accessor("linkedAccounts", {
|
||||
cell: (cell) => {
|
||||
const externalWallets = getExternalWallets(cell.getValue());
|
||||
if (externalWallets.length === 0) {
|
||||
return <span className="text-muted-foreground text-xs">None</span>;
|
||||
}
|
||||
return (
|
||||
<div className="space-y-1">
|
||||
{externalWallets.slice(0, 2).map((account) => {
|
||||
const address = account.details?.address as string | undefined;
|
||||
return address ? (
|
||||
<div
|
||||
key={`external-${address}-${account.details?.id}`}
|
||||
className="text-xs"
|
||||
>
|
||||
<WalletAddress address={address} client={props.client} />
|
||||
</div>
|
||||
) : null;
|
||||
})}
|
||||
{externalWallets.length > 2 && (
|
||||
<span className="text-muted-foreground text-xs">
|
||||
+{externalWallets.length - 2} more
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
header: "External Wallets",
|
||||
id: "external_wallets",
|
||||
}),
|
||||
columnHelper.accessor("wallets", {
|
||||
cell: (cell) => {
|
||||
const value = cell.getValue()[0]?.createdAt;
|
||||
@@ -172,11 +206,18 @@ export function InAppWalletUsersPageContent(
|
||||
});
|
||||
const csv = Papa.unparse(
|
||||
usersWallets.map((row) => {
|
||||
const externalWallets = getExternalWallets(row.linkedAccounts);
|
||||
const externalWalletAddresses = externalWallets
|
||||
.map((account) => account.details?.address)
|
||||
.filter(Boolean)
|
||||
.join(", ");
|
||||
|
||||
return {
|
||||
address: row.wallets[0]?.address || "Uninitialized",
|
||||
created: row.wallets[0]?.createdAt
|
||||
? format(new Date(row.wallets[0].createdAt), "MMM dd, yyyy")
|
||||
: "Wallet not created yet",
|
||||
external_wallets: externalWalletAddresses || "None",
|
||||
login_methods: row.linkedAccounts.map((acc) => acc.type).join(", "),
|
||||
user_identifier: getUserIdentifier(row.linkedAccounts),
|
||||
};
|
||||
|
||||
+3
@@ -33,6 +33,9 @@ export async function searchUsers(
|
||||
case "address":
|
||||
url.searchParams.append("address", query);
|
||||
break;
|
||||
case "externalWallet":
|
||||
url.searchParams.append("externalWalletAddress", query);
|
||||
break;
|
||||
}
|
||||
|
||||
const response = await fetch(url.toString(), {
|
||||
|
||||
+6
-1
@@ -1 +1,6 @@
|
||||
export type SearchType = "email" | "phone" | "id" | "address";
|
||||
export type SearchType =
|
||||
| "email"
|
||||
| "phone"
|
||||
| "id"
|
||||
| "address"
|
||||
| "externalWallet";
|
||||
|
||||
@@ -22,10 +22,10 @@ export function EmptyState() {
|
||||
<AnimatedIcons />
|
||||
<div className="flex flex-col gap-0.5 text-center">
|
||||
<h3 className="font-semibold text-2xl text-foreground">
|
||||
Get Started with the Connect SDK
|
||||
Get Started with the TypeScript SDK
|
||||
</h3>
|
||||
<p className="text-base text-muted-foreground">
|
||||
Add the Connect SDK to your app to start collecting analytics.
|
||||
Add the TypeScript SDK to your app to start collecting analytics.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center justify-center gap-2">
|
||||
|
||||
@@ -40,7 +40,7 @@ function BuyOnchainAsset() {
|
||||
return (
|
||||
<CodeExample
|
||||
code={`import { claimTo } from "thirdweb/extensions/erc1155";
|
||||
import { PayEmbed, useActiveAccount } from "thirdweb/react";
|
||||
import { TransactionWidget, useActiveAccount } from "thirdweb/react";
|
||||
|
||||
function App() {
|
||||
const account = useActiveAccount();
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "next build",
|
||||
"format": "biome format ./src --write",
|
||||
"create-index": "pnpm tsx scripts/createEmptySearchIndex.ts",
|
||||
"dev": "next dev",
|
||||
"extract-llm-content": "pnpm tsx scripts/extractLLMData.ts",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
@@ -339,6 +339,11 @@ const solidityRedirects = {
|
||||
"/solidity/extensions/primarysale":
|
||||
"/contracts/build/extensions/general/PrimarySale",
|
||||
"/solidity/extensions/royalty": "/contracts/build/extensions/general/Royalty",
|
||||
|
||||
// contracts -> tokens
|
||||
"/contracts/deploy/:path*": "/contracts/deploy",
|
||||
"/contracts/build": "/tokens/build",
|
||||
"/contracts/build/:path*": "/tokens/build/:path*",
|
||||
};
|
||||
|
||||
const extensionsTable = "/typescript/v4/extensions#all-available-extensions";
|
||||
@@ -712,6 +717,7 @@ const walletRedirects = {
|
||||
|
||||
const paymentRedirects = {
|
||||
"/pay": "/payments",
|
||||
"/pay/:path*": "/payments",
|
||||
"/checkouts": "/payments",
|
||||
"/checkouts/api-reference": "/payments/nft-checkout/api-reference",
|
||||
"/checkouts/checkout-link": "/payments/nft-checkout/checkout-link",
|
||||
@@ -920,7 +926,6 @@ const otherRedirects = {
|
||||
"/connect/account-abstraction": "/connect/account-abstraction/overview",
|
||||
// connect
|
||||
"/connect/connect": "/connect/sign-in",
|
||||
"/connect/ecosystems/:path*": "/connect/wallet/overview",
|
||||
"/connect/embedded-wallet/how-to/get-embedded-wallet-details-on-server":
|
||||
"/connect/in-app-wallet/how-to/get-in-app-wallet-details-on-server",
|
||||
"/connect/in-app-wallet/how-to/get-in-app-wallet-details-on-server":
|
||||
@@ -1016,15 +1021,14 @@ const otherRedirects = {
|
||||
"/unity/wallets/providers/account-abstraction",
|
||||
"/wallet/get-started/overview": "/connect/wallet/overview",
|
||||
// connect > wallets
|
||||
"/connect/:path*": "/wallets/:path*",
|
||||
"/connect/wallet/:path*": "/wallets/:path*",
|
||||
"/connect/auth/:path*": "/wallets/auth/:path*",
|
||||
"/connect/connect/:path*": "/wallets/connect/:path*",
|
||||
"/connect/embedded-wallet/:path*": "/wallets/embedded-wallet/:path*",
|
||||
"/connect": "/wallets",
|
||||
"/connect/wallet/sign-in-methods/configure": "/wallets/users",
|
||||
"/connect/wallet/server": "/wallets/server",
|
||||
"/connect/account-abstraction/get-started": "/wallets/sponsor-gas",
|
||||
"/connect/account-abstraction/:path*": "/wallets/sponsor-gas",
|
||||
"/connect/pay/:path*": "/payments",
|
||||
"/connect/ecosystems/:path*": "/wallets/ecosystem/set-up",
|
||||
"/connect/:path*": "/wallets",
|
||||
"/wallets/in-app-wallet/custom-auth/configuration": "/wallets/custom-auth",
|
||||
"/connect/wallets/user-management/link-multiple-identity":
|
||||
"/wallets/link-profiles",
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
TableOfContentsIcon,
|
||||
} from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { DocSearch } from "@/components/others/DocSearch";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -48,12 +48,8 @@ const links = [
|
||||
name: "Contracts",
|
||||
},
|
||||
{
|
||||
href: "/insight",
|
||||
name: "Insight",
|
||||
},
|
||||
{
|
||||
href: "/vault",
|
||||
name: "Vault",
|
||||
href: "/tokens",
|
||||
name: "Tokens",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -86,7 +82,7 @@ export const connectLinks: Array<{
|
||||
icon: React.FC<{ className?: string }>;
|
||||
}> = [
|
||||
{
|
||||
href: "/connect",
|
||||
href: "/wallets",
|
||||
icon: TableOfContentsIcon,
|
||||
name: "Overview",
|
||||
},
|
||||
@@ -123,10 +119,6 @@ export const connectLinks: Array<{
|
||||
] as const;
|
||||
|
||||
const apisLinks = [
|
||||
{
|
||||
href: "https://engine.thirdweb.com/reference",
|
||||
name: "Engine",
|
||||
},
|
||||
{
|
||||
href: "https://insight.thirdweb.com/reference",
|
||||
name: "Insight",
|
||||
@@ -140,7 +132,7 @@ const apisLinks = [
|
||||
name: "Payments",
|
||||
},
|
||||
{
|
||||
href: "/connect/account-abstraction/api",
|
||||
href: "/bundler",
|
||||
name: "Bundler",
|
||||
},
|
||||
];
|
||||
@@ -195,13 +187,12 @@ const supportLinks = [
|
||||
|
||||
export function Header() {
|
||||
const [showBurgerMenu, setShowBurgerMenu] = useState(false);
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
|
||||
return (
|
||||
<header className="flex w-full flex-col gap-2 border-b bg-background pt-4 px-4 lg:px-8 overflow-hidden">
|
||||
<header className="flex w-full flex-col gap-2 border-b bg-background p-4 xl:pb-0 lg:px-8 overflow-hidden">
|
||||
{/* Top row */}
|
||||
<div className="container flex items-center justify-between gap-6">
|
||||
{/* Top row */}
|
||||
<div className="flex items-center gap-2">
|
||||
<Link
|
||||
aria-label="thirdweb Docs"
|
||||
@@ -223,7 +214,7 @@ export function Header() {
|
||||
href="https://github.com/thirdweb-dev"
|
||||
target="_blank"
|
||||
>
|
||||
<GithubIcon className="mx-3 size-6" />
|
||||
<GithubIcon className="size-6 lg:size-5" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -236,25 +227,21 @@ export function Header() {
|
||||
</div>
|
||||
|
||||
<div className="hidden xl:block">
|
||||
<Button
|
||||
onClick={() => {
|
||||
router.push("/chat");
|
||||
}}
|
||||
>
|
||||
<MessageCircleIcon className="mr-2 size-4" />
|
||||
Ask AI
|
||||
<Button asChild>
|
||||
<Link href="/chat">
|
||||
<MessageCircleIcon className="mr-2 size-4" />
|
||||
Ask AI
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-1 xl:hidden">
|
||||
<ThemeSwitcher className="border-none bg-transparent" />
|
||||
<DocSearch variant="icon" />
|
||||
<Button
|
||||
className="p-2"
|
||||
onClick={() => router.push("/chat")}
|
||||
variant="ghost"
|
||||
>
|
||||
<MessageCircleIcon className="size-7" />
|
||||
<Button className="p-2" asChild variant="ghost">
|
||||
<Link href="/chat">
|
||||
<MessageCircleIcon className="size-6" />
|
||||
</Link>
|
||||
</Button>
|
||||
<Button
|
||||
className="p-2"
|
||||
@@ -268,13 +255,13 @@ export function Header() {
|
||||
</div>
|
||||
|
||||
{/* Bottom row - hidden on mobile */}
|
||||
<div className="container hidden items-center justify-between gap-6 xl:flex">
|
||||
<div className="container hidden items-center justify-between gap-6 xl:flex mt-1">
|
||||
<nav className="flex grow gap-5">
|
||||
<ul className="flex flex-row items-center gap-5">
|
||||
<ul className="flex flex-row items-center gap-0 mb-1">
|
||||
{links.map((link) => {
|
||||
return (
|
||||
<li
|
||||
className="flex items-center py-4 relative overflow-hidden"
|
||||
className="flex items-center py-2 relative px-2.5 hover:text-foreground"
|
||||
key={link.href}
|
||||
onClick={() => {
|
||||
setShowBurgerMenu(false);
|
||||
@@ -285,7 +272,7 @@ export function Header() {
|
||||
>
|
||||
<NavLink href={link.href} name={link.name} />
|
||||
{pathname.includes(link.href) && (
|
||||
<div className="bg-violet-700 h-1 inset-x-0.5 rounded-full absolute -bottom-0.5" />
|
||||
<div className="bg-violet-700 h-[2px] inset-x-0 rounded-full absolute -bottom-1" />
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ export const metadata = createMetadata({
|
||||
|
||||
# API Keys
|
||||
|
||||
Each thirdweb project is equipped with an API key to use thirdweb's infrastructure services including [Storage](/infrastructure/storage/overview), [RPC Edge](/infrastructure/rpc-edge/overview), [Account Abstraction infrastructure](/connect/account-abstraction), and [In-App Wallets](/connect/in-app-wallet/overview).
|
||||
Each thirdweb project is equipped with an API key to use thirdweb's infrastructure services including [Storage](/infrastructure/storage/overview), [RPC Edge](/infrastructure/rpc-edge/overview), [Account Abstraction infrastructure](/bundler), and [In-App Wallets](/wallets).
|
||||
|
||||
## Services
|
||||
|
||||
|
||||
@@ -64,37 +64,6 @@ export async function GET(request: Request) {
|
||||
width: "50%",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
gap: "10px",
|
||||
marginBottom: "40px",
|
||||
}}
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
height={50 / 1.7}
|
||||
src={`${BAST_URL}/icons/thirdweb-logo.svg`}
|
||||
style={{
|
||||
display: "flex",
|
||||
}}
|
||||
width={300 / 1.7}
|
||||
/>
|
||||
|
||||
<div
|
||||
style={{
|
||||
color: "white",
|
||||
fontFamily: "Inter",
|
||||
fontSize: "26px",
|
||||
fontWeight: 600,
|
||||
marginTop: "2px",
|
||||
}}
|
||||
>
|
||||
Docs
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
@@ -107,26 +76,6 @@ export async function GET(request: Request) {
|
||||
>
|
||||
{title}
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
background: "white",
|
||||
borderRadius: "10px",
|
||||
color: "black",
|
||||
fontFamily: "Inter",
|
||||
fontSize: "24px",
|
||||
fontWeight: 600,
|
||||
padding: "14px 20px",
|
||||
}}
|
||||
>
|
||||
Read More
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<img
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { DocLayout } from "@/components/Layouts/DocLayout";
|
||||
|
||||
export default async function Layout(props: { children: React.ReactNode }) {
|
||||
return (
|
||||
<DocLayout
|
||||
editPageButton={true}
|
||||
sideBar={{
|
||||
name: "Bundler",
|
||||
links: [],
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
</DocLayout>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,490 @@
|
||||
# Thirdweb Bundler - API Reference
|
||||
|
||||
The Thirdweb Bundler is a service that provides Account Abstraction (ERC-4337 and EIP-7702) bundler functionality with integrated paymaster services, zkSync chains support, and EIP-7702 transaction delegation.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Url format](#url-format)
|
||||
- [Authentication](#authentication)
|
||||
- [Request Format](#request-format)
|
||||
- [Paymaster Methods](#paymaster-methods)
|
||||
- [User Operation Methods](#user-operation-methods)
|
||||
- [Gas Price Methods](#gas-price-methods)
|
||||
- [Status and Tracking Methods](#status-and-tracking-methods)
|
||||
- [zkSync-Specific Methods](#zksync-specific-methods)
|
||||
- [EIP-7702 Methods](#eip-7702-methods)
|
||||
- [Standard ERC-4337 Methods](#standard-erc-4337-methods)
|
||||
- [Error Responses](#error-responses)
|
||||
- [Policy Enforcement](#policy-enforcement)
|
||||
|
||||
## Url format
|
||||
|
||||
- **Chain Parameter**: the chain id is always specified in the subdomain (e.g., `<chain_id>.bundler.thirdweb.com`)
|
||||
- **Version Parameter**: the version is specified in the path, we recommend using `/v2`
|
||||
|
||||
```
|
||||
https://<chain_id>.bundler.thirdweb.com/v2
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
All requests require authentication via:
|
||||
|
||||
- **Client ID**: Provided as `X-Client-Id: <client_id>` header - used for frontend authentication
|
||||
- **Secret Key**: Provided as `X-Secret-Key: <secret_key>` header - used for backend authentication
|
||||
|
||||
## Request Format
|
||||
|
||||
All RPC requests follow the JSON-RPC 2.0 specification:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"jsonrpc": "2.0",
|
||||
"method": "<method_name>",
|
||||
"params": [...]
|
||||
}
|
||||
```
|
||||
|
||||
## Paymaster Methods
|
||||
|
||||
### `pm_sponsorUserOperation`
|
||||
|
||||
**Purpose**: Sponsors a user operation by providing paymaster data to cover gas costs.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"sender": "0x...", // Address of the smart account
|
||||
"nonce": "0x...", // Nonce for the operation
|
||||
"initCode": "0x...", // Account initialization code (if needed)
|
||||
"callData": "0x...", // The call data to execute
|
||||
"callGasLimit": "0x...", // Gas limit for the call
|
||||
"verificationGasLimit": "0x...", // Gas limit for verification
|
||||
"preVerificationGas": "0x...", // Pre-verification gas
|
||||
"maxFeePerGas": "0x...", // Maximum fee per gas
|
||||
"maxPriorityFeePerGas": "0x...", // Maximum priority fee per gas
|
||||
"paymasterAndData": "0x...", // Paymaster data (EntryPoint v0.6)
|
||||
// OR for EntryPoint v0.7:
|
||||
"paymaster": "0x...", // Paymaster address
|
||||
"paymasterData": "0x...", // Paymaster data
|
||||
"paymasterVerificationGasLimit": "0x...",
|
||||
"paymasterPostOpGasLimit": "0x..."
|
||||
},
|
||||
"0x...", // Entry point address
|
||||
"0x...", // Chain ID (hex)
|
||||
]
|
||||
```
|
||||
|
||||
**Response**:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"jsonrpc": "2.0",
|
||||
"result": {
|
||||
"paymaster": "0x...", // Paymaster address
|
||||
"paymasterData": "0x...", // Paymaster data
|
||||
"paymasterAndData": "0x..." // Combined paymaster data (v0.6)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `pm_getPaymasterData`
|
||||
|
||||
**Purpose**: Gets paymaster data for sponsoring a user operation (functionally equivalent to `pm_sponsorUserOperation`).
|
||||
|
||||
**Parameters**: Same as `pm_sponsorUserOperation`
|
||||
**Response**: Same as `pm_sponsorUserOperation`
|
||||
|
||||
### `pm_getPaymasterStubData`
|
||||
|
||||
**Purpose**: Gets stub paymaster data for gas estimation purposes without actual sponsorship.
|
||||
|
||||
**Parameters**: Same as `pm_sponsorUserOperation`
|
||||
**Response**: Similar to `pm_sponsorUserOperation` but with placeholder data for estimation.
|
||||
|
||||
### `pm_getAcceptedPaymentTokens`
|
||||
|
||||
**Purpose**: Returns the list of tokens accepted for gas payments by the paymaster.
|
||||
|
||||
**Parameters**: `[]`
|
||||
|
||||
**Response**:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"jsonrpc": "2.0",
|
||||
"result": {
|
||||
"acceptedTokens": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## User Operation Methods
|
||||
|
||||
### `eth_estimateUserOperationGas`
|
||||
|
||||
**Purpose**: Estimates gas limits required for a user operation.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"sender": "0x...", // Smart account address
|
||||
"nonce": "0x...", // Account nonce
|
||||
"initCode": "0x...", // Initialization code (if deploying)
|
||||
"callData": "0x...", // Transaction call data
|
||||
"maxFeePerGas": "0x...", // Maximum fee per gas
|
||||
"maxPriorityFeePerGas": "0x..." // Maximum priority fee
|
||||
},
|
||||
"0x...", // Entry point address
|
||||
{} // State overrides (optional)
|
||||
]
|
||||
```
|
||||
|
||||
**Response**:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"jsonrpc": "2.0",
|
||||
"result": {
|
||||
"preVerificationGas": "0x...", // Pre-verification gas
|
||||
"verificationGasLimit": "0x...", // Verification gas limit
|
||||
"callGasLimit": "0x...", // Call gas limit
|
||||
// For EntryPoint v0.7:
|
||||
"paymasterVerificationGasLimit": "0x...",
|
||||
"paymasterPostOpGasLimit": "0x..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `eth_sendUserOperation`
|
||||
|
||||
**Purpose**: Submits a user operation to the bundler for execution on-chain.
|
||||
|
||||
**Parameters**: Same format as the user operation object used in other methods.
|
||||
|
||||
**Response**:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"jsonrpc": "2.0",
|
||||
"result": "0x..." // User operation hash
|
||||
}
|
||||
```
|
||||
|
||||
## Gas Price Methods
|
||||
|
||||
### `thirdweb_getUserOperationGasPrice`
|
||||
|
||||
**Purpose**: Gets current gas prices optimized for user operations.
|
||||
|
||||
**Parameters**: `[]`
|
||||
|
||||
**Response**:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"jsonrpc": "2.0",
|
||||
"result": {
|
||||
"maxFeePerGas": "0x...", // Recommended max fee per gas
|
||||
"maxPriorityFeePerGas": "0x..." // Recommended priority fee
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Status and Tracking Methods
|
||||
|
||||
### `thirdweb_getUserOperationStatus`
|
||||
|
||||
**Purpose**: Gets the current status of a submitted user operation.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
```json
|
||||
["0x..."] // User operation hash (hex string)
|
||||
```
|
||||
|
||||
**Response**:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"jsonrpc": "2.0",
|
||||
"result": {
|
||||
"status": "not_found|not_submitted|submitted|rejected|included|failed|queued",
|
||||
"transactionHash": "0x..." // Transaction hash (null if not yet included)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Status Values**:
|
||||
|
||||
- `not_found`: User operation not found
|
||||
- `not_submitted`: Not yet submitted to mempool
|
||||
- `submitted`: Submitted to mempool
|
||||
- `rejected`: Rejected by bundler
|
||||
- `included`: Successfully included in a block
|
||||
- `failed`: Transaction failed on-chain
|
||||
- `queued`: Queued for processing
|
||||
|
||||
## zkSync-Specific Methods
|
||||
|
||||
### `zk_paymasterData`
|
||||
|
||||
**Purpose**: Gets paymaster data for zkSync chains to enable gasless transactions.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"nonce": "0x...", // Transaction nonce
|
||||
"from": "0x...", // Sender address
|
||||
"to": "0x...", // Recipient address
|
||||
"gas": "0x...", // Gas limit
|
||||
"gasPrice": "0x...", // Gas price
|
||||
"value": "0x...", // ETH value to send
|
||||
"data": "0x...", // Transaction data
|
||||
"maxFeePerGas": "0x...", // EIP-1559 max fee
|
||||
"maxPriorityFeePerGas": "0x...", // EIP-1559 priority fee
|
||||
"chainId": "0x..." // Chain ID
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
**Response**:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"jsonrpc": "2.0",
|
||||
"result": {
|
||||
"paymaster": "0x...", // Paymaster contract address
|
||||
"paymasterInput": "0x..." // Encoded paymaster input data
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `zk_broadcastTransaction`
|
||||
|
||||
**Purpose**: Broadcasts a signed transaction on zkSync chains.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"nonce": "0x...",
|
||||
"from": "0x...",
|
||||
"to": "0x...",
|
||||
"gas": "0x...",
|
||||
"gasPrice": "0x...",
|
||||
"value": "0x...",
|
||||
"data": "0x...",
|
||||
"maxFeePerGas": "0x...",
|
||||
"maxPriorityFeePerGas": "0x...",
|
||||
"chainId": "0x...",
|
||||
"signedTransaction": "0x..." // Raw signed transaction bytes
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
**Response**:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"jsonrpc": "2.0",
|
||||
"result": "0x..." // Transaction hash
|
||||
}
|
||||
```
|
||||
|
||||
## EIP-7702 Methods
|
||||
|
||||
### `tw_execute`
|
||||
|
||||
**Purpose**: Executes transactions using EIP-7702 (Account Abstraction via Authorization Lists). This enables EOAs to temporarily act as smart contracts.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
```json
|
||||
[
|
||||
"0x...", // EOA address that will execute the calls
|
||||
{
|
||||
"calls": [
|
||||
{
|
||||
"target": "0x...", // Contract address to call
|
||||
"value": "0x...", // ETH value to send (hex)
|
||||
"data": "0x..." // Call data
|
||||
}
|
||||
// ... more calls
|
||||
],
|
||||
"uid": "0x..." // Unique identifier for the batch (bytes32)
|
||||
},
|
||||
"0x...", // Signature authorizing the execution
|
||||
{
|
||||
// Authorization list (optional)
|
||||
"chainId": 1,
|
||||
"address": "0x...",
|
||||
"nonce": "0x...",
|
||||
"yParity": 0,
|
||||
"r": "0x...",
|
||||
"s": "0x..."
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
**Response**:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"jsonrpc": "2.0",
|
||||
"result": {
|
||||
"queueId": "..." // Queue ID for tracking the transaction
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `tw_getTransactionHash`
|
||||
|
||||
**Purpose**: Gets the transaction hash for a queued EIP-7702 transaction.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
```json
|
||||
["queue_id"] // Queue ID returned from tw_execute
|
||||
```
|
||||
|
||||
**Response**:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"jsonrpc": "2.0",
|
||||
"result": {
|
||||
"transactionHash": "0x..." // Transaction hash (null if not yet mined)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Standard ERC-4337 Methods
|
||||
|
||||
The service supports all the standard ERC-4337 bundler methods:
|
||||
|
||||
- `eth_chainId` - Returns the current chain ID
|
||||
- `eth_getUserOperationByHash` - Retrieves user operation by hash
|
||||
- `eth_getUserOperationReceipt` - Gets the receipt for a user operation
|
||||
- `eth_supportedEntryPoints` - Lists supported EntryPoint contracts
|
||||
- Any other standard bundler RPC methods defined in ERC-4337
|
||||
|
||||
## Error Responses
|
||||
|
||||
All methods may return error responses following the JSON-RPC 2.0 error format:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"jsonrpc": "2.0",
|
||||
"error": {
|
||||
"code": 400,
|
||||
"message": "Detailed error description"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Common Error Codes
|
||||
|
||||
- **400**: Invalid parameters, malformed request, or unsupported chain
|
||||
- **401**: Invalid authentication credentials or insufficient permissions
|
||||
- **500**: Internal server error
|
||||
- **502**: Upstream bundler provider error
|
||||
|
||||
### Example Error Scenarios
|
||||
|
||||
```json
|
||||
// Invalid chain
|
||||
{
|
||||
"error": "Invalid chain: unsupported_chain",
|
||||
"chain": "unsupported_chain",
|
||||
"code": 400
|
||||
}
|
||||
|
||||
// Mainnet access denied
|
||||
{
|
||||
"error": "Mainnets not enabled for this account, please enable billing...",
|
||||
"code": 401
|
||||
}
|
||||
|
||||
// Invalid user operation hash
|
||||
{
|
||||
"error": "Invalid userOpHash parameter",
|
||||
"code": 400
|
||||
}
|
||||
```
|
||||
|
||||
## Policy Enforcement
|
||||
|
||||
Paymaster methods support policy-based access control. When a transaction is subject to policy evaluation:
|
||||
|
||||
### Policy Check Process
|
||||
|
||||
1. The system evaluates paymaster requests against configured policies
|
||||
2. Policies can restrict based on:
|
||||
- Contract addresses being called
|
||||
- Transaction data
|
||||
- Gas limits
|
||||
- Sender addresses
|
||||
- Custom endpoint logic
|
||||
|
||||
### Policy Rejection Response
|
||||
|
||||
If a request is rejected by policy, the response format is:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"jsonrpc": "2.0",
|
||||
"result": {
|
||||
"policyId": "policy_123", // ID of the policy that rejected the request
|
||||
"reason": "Transaction rejected by policy: Unauthorized contract call"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Affected Methods
|
||||
|
||||
Policy enforcement applies to:
|
||||
|
||||
- `pm_sponsorUserOperation`
|
||||
- `pm_getPaymasterData`
|
||||
- `zk_paymasterData`
|
||||
|
||||
## Rate Limits and Quotas
|
||||
|
||||
- Rate limits may apply based on your billing plan
|
||||
- Mainnet access requires billing information
|
||||
- Testnet access is available on free plans
|
||||
|
||||
## Supported Networks
|
||||
|
||||
For the most up-to-date list of supported chains, check the [thirdweb dashboard](https://thirdweb.com/dashboard).
|
||||
|
||||
## SDK Integration
|
||||
|
||||
For easier integration, consider using the thirdweb SDKs:
|
||||
|
||||
- [JavaScript/TypeScript SDK](/typescript)
|
||||
- [React SDK](/react)
|
||||
- [Unity SDK](/unity)
|
||||
- [Dotnet SDK](/dotnet)
|
||||
- [Unreal Engine SDK](/unreal)
|
||||
@@ -0,0 +1,57 @@
|
||||
# Deploy Contracts
|
||||
|
||||
You can deploy contracts via CLI or programatically.
|
||||
|
||||
## Deploying via CLI
|
||||
|
||||
From your forge or hardhat project, you can deploy your contract with a single command.
|
||||
|
||||
```bash
|
||||
npx thirdweb deploy -k <project-secret-key>
|
||||
```
|
||||
|
||||
You can also publish your contract to be deployable by anyone on any chain.
|
||||
|
||||
```bash
|
||||
npx thirdweb publish -k <project-secret-key>
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Deploying via SDK
|
||||
|
||||
You can deploy contracts from ABI and bytecode.
|
||||
|
||||
```ts
|
||||
import { deployContract } from "thirdweb/deploys";
|
||||
|
||||
const address = await deployContract({
|
||||
client,
|
||||
chain,
|
||||
bytecode: "0x...",
|
||||
abi: contractAbi,
|
||||
constructorParams: {
|
||||
param1: "value1",
|
||||
param2: 123,
|
||||
},
|
||||
salt, // optional: salt enables deterministic deploys
|
||||
});
|
||||
```
|
||||
|
||||
Or alternatively, you can deploy a contract from a previously published contract.
|
||||
|
||||
```ts
|
||||
import { deployPublishedContract } from "thirdweb/deploys";
|
||||
|
||||
const address = await deployPublishedContract({
|
||||
client,
|
||||
chain,
|
||||
account,
|
||||
contractId: "MyPublishedContract",
|
||||
contractParams: {
|
||||
param1: "value1",
|
||||
param2: 123,
|
||||
},
|
||||
publisher: "0x...", // optional, defaults to the thirdweb deployer
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
# Listening to Events
|
||||
|
||||
The recommended way to listen to contract events is to use the [`getContractEvents`](/references/typescript/v5/getContractEvents) function and passing a prepared event with the Solidity event signature and the params. This is type-safe based on the Solidity event signature you define. You can get your desired contract event signature from the solidity code directly.
|
||||
|
||||
```ts
|
||||
import { getContractEvents, prepareEvent } from "thirdweb";
|
||||
|
||||
const myEvent = prepareEvent({
|
||||
signature: "event Transfer(address indexed from, address indexed to, uint256 value)",
|
||||
});
|
||||
|
||||
const events = await getContractEvents({
|
||||
contract: myContract,
|
||||
events: [myEvent],
|
||||
});
|
||||
```
|
||||
|
||||
### Using standard event definitions
|
||||
|
||||
You can also use the standard event definitions from the SDK to define the events you want to listen to.
|
||||
|
||||
```ts
|
||||
import { getContractEvents } from "thirdweb";
|
||||
import { transferEvent } from "thirdweb/extensions/erc20";
|
||||
|
||||
const events = await getContractEvents({
|
||||
contract: myContract,
|
||||
events: [transferEvent()],
|
||||
});
|
||||
```
|
||||
|
||||
### Generating all read functions and events for a deployed contract
|
||||
|
||||
Using the CLI, you can generate optimized functions for all the possible calls to a contract. This saves you time and precomputes all the necessary encoding.
|
||||
|
||||
```shell
|
||||
npx thirdweb generate <contractId>/<contractAddress>
|
||||
```
|
||||
|
||||
Read more on how to [generate extension functions using the CLI](/contracts/generate).
|
||||
@@ -0,0 +1,85 @@
|
||||
import { fetchTypeScriptDoc } from "@/app/references/components/TDoc/fetchDocs/fetchTypeScriptDoc";
|
||||
import { getCustomTag } from "@/app/references/components/TDoc/utils/getSidebarLinkgroups";
|
||||
import { DocLink, Heading, Paragraph } from "@/components/Document";
|
||||
import { Table, TBody, Td, Th, Tr } from "@/components/Document/Table";
|
||||
|
||||
export default async function ExtensionPage() {
|
||||
const docs = await fetchTypeScriptDoc();
|
||||
const extensions = [
|
||||
...new Set(
|
||||
docs.functions
|
||||
?.filter((f) => {
|
||||
const [extension] = getCustomTag(f) || [];
|
||||
return extension === "@extension";
|
||||
})
|
||||
?.map((f) => {
|
||||
const [, extensionName] = getCustomTag(f) || [];
|
||||
return extensionName;
|
||||
})
|
||||
.filter((item) => item !== undefined) || [],
|
||||
),
|
||||
];
|
||||
|
||||
const overrides: Record<string, { name?: string; description?: string }> = {
|
||||
common: {
|
||||
description: "Common contract extensions",
|
||||
name: "Common",
|
||||
},
|
||||
erc20: { description: "ERC20 token standard extensions" },
|
||||
erc721: { description: "ERC721 token standard extensions" },
|
||||
erc1155: { description: "ERC1155 token standard extensions" },
|
||||
erc4337: { description: "ERC4337 account abstraction extensions" },
|
||||
erc4626: { description: "ERC4626 Tokenized Vaults extensions" },
|
||||
farcaster: { description: "Farcaster protocol extensions" },
|
||||
lens: { description: "Lens protocol extensions" },
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<Heading anchorId="built-in-extensions" level={1}>
|
||||
Built-in extensions for common standards
|
||||
</Heading>
|
||||
<Paragraph>
|
||||
The SDK comes packed with a set of built-in extensions for common
|
||||
standards. These extensions are designed to make it easy to interact
|
||||
with popular contracts and protocols. They are available as part of the
|
||||
SDK and can be used in your application without any additional setup.
|
||||
</Paragraph>
|
||||
<Table>
|
||||
<TBody>
|
||||
<Tr>
|
||||
<Th>Standard</Th>
|
||||
<Th>Import Path</Th>
|
||||
<Th>Description</Th>
|
||||
</Tr>
|
||||
|
||||
{extensions.map((item) => {
|
||||
return (
|
||||
<Tr key={item}>
|
||||
<Td>{overrides[item]?.name ?? item}</Td>
|
||||
<Td>
|
||||
<DocLink
|
||||
href={`/references/typescript/v5/functions#${item.toLowerCase()}`}
|
||||
>
|
||||
thirdweb/extensions/{item.toLowerCase()}
|
||||
</DocLink>
|
||||
</Td>
|
||||
<Td>{overrides[item]?.description ?? `${item} extensions`}</Td>
|
||||
</Tr>
|
||||
);
|
||||
})}
|
||||
</TBody>
|
||||
</Table>
|
||||
<Paragraph>
|
||||
More extensions are being added regularly. Anyone can{" "}
|
||||
<DocLink href="/typescript/v5/extensions/create">
|
||||
create an extension
|
||||
</DocLink>{" "}
|
||||
and contribute it back to the repository. You can also{" "}
|
||||
<DocLink href="/typescript/v5/extensions/generate">
|
||||
generate extensions
|
||||
</DocLink>{" "}
|
||||
for any deployed contract.
|
||||
</Paragraph>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
# Generating extensions
|
||||
|
||||
You can generate precompiled, optimized extensions for any deployed contract using the thirdweb CLI.
|
||||
|
||||
The thirdweb SDK comes with a CLI that can be run with your package manager of choice.
|
||||
|
||||
```bash
|
||||
npx thirdweb generate <chainId>/<contract-address>
|
||||
```
|
||||
|
||||
This will generate a new `thirdweb` directory in your own project, containing the precompiled extension for the contract at the given address.
|
||||
|
||||
### Example: Generating an extension for a USDC contract on Optimism
|
||||
|
||||
```bash
|
||||
npx thirdweb generate 10/0x0b2c639c533813f4aa9d7837caf62653d097ff85
|
||||
```
|
||||
|
||||
This will generate the following file `thirdweb/10/0x0b2c639c533813f4aa9d7837caf62653d097ff85.ts` in your project, containing:
|
||||
|
||||
- Precompiled, type-safe event definitions
|
||||
- Precompiled, type-safe function definitions
|
||||
|
||||
You can inspect the generated code, modify it, and use it in your project.
|
||||
|
||||
### Example: Using a generated extension function
|
||||
|
||||
```typescript
|
||||
import { permit } from "/thirdweb/10/0x0b2c639c533813f4aa9d7837caf62653d097ff85";
|
||||
|
||||
const contract = getContract({
|
||||
client,
|
||||
chain: optimism,
|
||||
address: USDC_ADDRESS,
|
||||
});
|
||||
|
||||
// Type-safe function to do a permit transaction
|
||||
const transaction = permit({
|
||||
owner: ...,
|
||||
spender: ...,
|
||||
value: ...,
|
||||
deadline: ...,
|
||||
signature: ...,
|
||||
});
|
||||
await sendTransaction({ transaction, account });
|
||||
```
|
||||
|
||||
### Example: Using a generated event
|
||||
|
||||
```typescript
|
||||
import { transferEvent } from "/thirdweb/10/0x0b2c639c533813f4aa9d7837caf62653d097ff85";
|
||||
|
||||
const contract = getContract({
|
||||
client,
|
||||
chain: optimism,
|
||||
address: USDC_ADDRESS,
|
||||
});
|
||||
|
||||
// Type-safe event listener
|
||||
const events = await getContractEvents({
|
||||
contract,
|
||||
events: [
|
||||
transferEvent({
|
||||
from: ...,
|
||||
to: ...,
|
||||
})
|
||||
],
|
||||
});
|
||||
```
|
||||
@@ -12,10 +12,10 @@ export default async function Layout(props: { children: React.ReactNode }) {
|
||||
|
||||
export const metadata = createMetadata({
|
||||
description:
|
||||
"Easily create, deploy, and manage smart contracts on any EVM compatible blockchain",
|
||||
"Easily read, write, deploy, and listen to contract events on any EVM compatible blockchain",
|
||||
image: {
|
||||
icon: "contract",
|
||||
title: "thirdweb contracts",
|
||||
title: "Contracts",
|
||||
},
|
||||
title: "thirdweb Contracts",
|
||||
title: "Contracts",
|
||||
});
|
||||
|
||||
@@ -1,119 +1,709 @@
|
||||
import { GithubTemplateCard, ExpandableGrid, createMetadata, OpenSourceCard, DocImage, ArticleIconCard, Grid } from "@doc";
|
||||
import SupportedChains from "../_images/supported-chains.png";
|
||||
import { ExternalLinkIcon } from "lucide-react";
|
||||
import {
|
||||
Callout,
|
||||
OpenSourceCard,
|
||||
createMetadata,
|
||||
InstallTabs,
|
||||
SDKCard,
|
||||
Grid,
|
||||
ArticleIconCard,
|
||||
Tabs,
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
TabsContent,
|
||||
} from "@doc";
|
||||
import {
|
||||
ReactIcon,
|
||||
TypeScriptIcon,
|
||||
UnityIcon,
|
||||
DotNetIcon,
|
||||
UnrealEngineIcon,
|
||||
EngineIcon,
|
||||
} from "@/icons";
|
||||
import { ExternalLink } from "lucide-react";
|
||||
|
||||
export const metadata = createMetadata({
|
||||
title: "thirdweb Contracts",
|
||||
description:
|
||||
"Tools to easily create, deploy, and manage smart contracts on any EVM compatible blockchain.",
|
||||
image: {
|
||||
title: "Contracts",
|
||||
icon: "contracts",
|
||||
},
|
||||
title: "Contracts",
|
||||
description: "Read, write, and deploy smart contracts on any EVM compatible blockchain.",
|
||||
});
|
||||
|
||||
# What are Contracts?
|
||||
# Get Started
|
||||
|
||||
Contracts is an end-to-end development suite which provides tools to develop, deploy, and manage smart contracts.
|
||||
Read, write, and deploy smart contracts on any EVM compatible blockchain.
|
||||
|
||||
---
|
||||
|
||||
<Tabs defaultValue="http">
|
||||
<TabsList>
|
||||
<TabsTrigger value="http" className="flex items-center gap-2 [&>p]:mb-0">
|
||||
<EngineIcon className="w-4 h-4 mr-2" />
|
||||
HTTP
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="typescript" className="flex items-center gap-2 [&>p]:mb-0">
|
||||
<TypeScriptIcon className="w-4 h-4 mr-2" />
|
||||
TypeScript
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="react" className="flex items-center gap-2 [&>p]:mb-0">
|
||||
<ReactIcon className="w-4 h-4 mr-2" />
|
||||
React
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="reactnative" className="flex items-center gap-2 [&>p]:mb-0">
|
||||
<ReactIcon className="w-4 h-4 mr-2" />
|
||||
React Native
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="unity" className="flex items-center gap-2 [&>p]:mb-0">
|
||||
<UnityIcon className="w-4 h-4 mr-2" />
|
||||
Unity
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="dotnet" className="flex items-center gap-2 [&>p]:mb-0">
|
||||
<DotNetIcon className="w-4 h-4 mr-2" />
|
||||
.NET
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="unreal" className="flex items-center gap-2 [&>p]:mb-0">
|
||||
<UnrealEngineIcon className="w-4 h-4 mr-2" />
|
||||
Unreal Engine
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="http">
|
||||
### Read a Contract
|
||||
|
||||
You can read contract data efficiently using the [contract read API](https://engine.thirdweb.com/reference).
|
||||
|
||||
```http
|
||||
GET /v1/contract/read
|
||||
Content-Type: application/json
|
||||
x-secret-key: <your-project-secret-key>
|
||||
|
||||
{
|
||||
"readOptions": {
|
||||
"chainId": "1" // your chain id
|
||||
"from": "0x...", // optional, if you want to read from a specific address
|
||||
},
|
||||
"params": [{
|
||||
"contractAddress": "0x...",
|
||||
"method": "function allowance(address owner, address spender)",
|
||||
"params": ["0x...", "0x..."],
|
||||
}],
|
||||
}
|
||||
```
|
||||
|
||||
You can batch multiple contract reads in a single request, and the response will be an array of results or errors.
|
||||
|
||||
### Write to a Contract
|
||||
|
||||
You can write to a contract using the [contract write API](https://engine.thirdweb.com/reference).
|
||||
|
||||
```http
|
||||
POST /v1/contract/write
|
||||
Content-Type: application/json
|
||||
x-secret-key: <your-project-secret-key>
|
||||
|
||||
{
|
||||
"executionOptions": {
|
||||
"from": "0x...", // your server wallet address
|
||||
"chainId": "1" // your chain id
|
||||
},
|
||||
"params": [{
|
||||
"contractAddress": "0x...",
|
||||
"method": "function transfer(address to, uint256 amount)",
|
||||
"params": ["0x...", "1000000000000000000"],
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
You can batch multiple contract writes in a single request, and the transactions will be batched atomically onchain.
|
||||
|
||||
### Deploy a Contract
|
||||
|
||||
You can deploy a contract using the [contract deploy API](https://engine.thirdweb.com/reference).
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="typescript">
|
||||
### Installation
|
||||
|
||||
Install the thirdweb SDK in your TypeScript project:
|
||||
|
||||
<InstallTabs
|
||||
npm="npm i thirdweb"
|
||||
yarn="yarn add thirdweb"
|
||||
pnpm="pnpm i thirdweb"
|
||||
bun="bun i thirdweb"
|
||||
/>
|
||||
|
||||
### Set up the Client
|
||||
|
||||
First, create a client instance to connect with thirdweb services:
|
||||
|
||||
```typescript
|
||||
import { createThirdwebClient } from "thirdweb";
|
||||
|
||||
// - clientId for client-side applications
|
||||
// - secretKey for server-side applications
|
||||
const client = createThirdwebClient({
|
||||
clientId: "YOUR_CLIENT_ID", // Get from your thirdweb dashboard
|
||||
});
|
||||
```
|
||||
|
||||
### Defining a Contract
|
||||
|
||||
You can define a contract using the [`getContract`](/references/typescript/v5/getContract) function.
|
||||
|
||||
```tsx
|
||||
import { getContract, defineChain } from "thirdweb";
|
||||
|
||||
const contract = await getContract({
|
||||
client,
|
||||
address: "0x...",
|
||||
chain: defineChain(8453),
|
||||
});
|
||||
```
|
||||
|
||||
### Read a Contract
|
||||
|
||||
You can read contract data using the [`readContract`](/references/typescript/v5/readContract) function.
|
||||
|
||||
```typescript
|
||||
import { readContract, getContract } from "thirdweb";
|
||||
import { defineChain } from "thirdweb/chains";
|
||||
|
||||
const data = await readContract({
|
||||
contract,
|
||||
method: "function allowance(address owner, address spender)",
|
||||
params: ["0x...", "0x..."],
|
||||
});
|
||||
```
|
||||
|
||||
### Write to a Contract
|
||||
|
||||
You can preapre a write transaction to a contract using the [`prepareContractCall`](/references/typescript/v5/prepareContractCall) function, then send it or enqueue it.
|
||||
|
||||
You can also use the [catalog of pre-built contract calls](/references/typescript/v5/functions#extensions) to easily prepare a transaction for standards like ERC20, ERC721, ERC1155, and more.
|
||||
|
||||
<Tabs defaultValue="frontend">
|
||||
<TabsList>
|
||||
<TabsTrigger value="frontend">Frontend</TabsTrigger>
|
||||
<TabsTrigger value="backend">Backend</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="frontend">
|
||||
On the frontend, you can use the [`sendTransaction`](/references/typescript/v5/sendTransaction) function to send a transaction from [user wallets](/wallets/users). The `account` parameter is the wallet that will be used to send the transaction. You can get an account object from a user wallet or a server wallet.
|
||||
|
||||
```typescript
|
||||
import { sendTransaction } from "thirdweb";
|
||||
|
||||
// connect user wallet
|
||||
const wallet = inAppWallet();
|
||||
const account = await wallet.connect({ client });
|
||||
|
||||
// prepare the contract write call
|
||||
const transaction = prepareContractCall({
|
||||
contract,
|
||||
method: "function transfer(address to, uint256 amount)",
|
||||
params: ["0x...", "1000000000000000000"],
|
||||
});
|
||||
|
||||
// send transaction
|
||||
const { transactionHash } = await sendTransaction({
|
||||
account,
|
||||
transaction,
|
||||
});
|
||||
|
||||
console.log("transaction sent", transactionHash);
|
||||
```
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="backend">
|
||||
On the backend, you can use a [server wallet](/wallets/servers) to enqueue a transaction. Enqueued transactions is recommended to not block your server. You can then monitor the transaction status using the [transaction monitor](/transactions/monitor) API.
|
||||
|
||||
```typescript
|
||||
import { Engine } from "thirdweb";
|
||||
|
||||
// get a server wallet
|
||||
const wallet = Engine.serverWallet({
|
||||
client,
|
||||
address: "0x...",
|
||||
});
|
||||
|
||||
// prepare the contract write call
|
||||
const transaction = prepareContractCall({
|
||||
contract,
|
||||
method: "function transfer(address to, uint256 amount)",
|
||||
params: ["0x...", "1000000000000000000"],
|
||||
});
|
||||
|
||||
// enqueue the transaction
|
||||
const { transactionId } = await wallet.enqueueTransaction({
|
||||
transaction,
|
||||
simulate: true, // optional, if you want to simulate the transaction before enqueuing it
|
||||
});
|
||||
|
||||
console.log("transaction enqueued", transactionId);
|
||||
```
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="react">
|
||||
### Installation
|
||||
|
||||
Install the thirdweb SDK in your React project:
|
||||
|
||||
<InstallTabs
|
||||
npm="npm i thirdweb"
|
||||
yarn="yarn add thirdweb"
|
||||
pnpm="pnpm i thirdweb"
|
||||
bun="bun i thirdweb"
|
||||
/>
|
||||
|
||||
|
||||
### Create a Client
|
||||
|
||||
First, create a client file (e.g., `thirdwebClient.ts`) for reuse throughout your app:
|
||||
|
||||
```typescript
|
||||
// thirdwebClient.ts
|
||||
import { createThirdwebClient } from "thirdweb";
|
||||
|
||||
export const client = createThirdwebClient({
|
||||
clientId: "YOUR_CLIENT_ID", // Get from your thirdweb dashboard
|
||||
});
|
||||
```
|
||||
|
||||
### Setup the Provider
|
||||
|
||||
Wrap your application with the ThirdwebProvider:
|
||||
|
||||
```tsx
|
||||
// app.tsx / _app.tsx
|
||||
import { ThirdwebProvider } from "thirdweb/react";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<ThirdwebProvider>
|
||||
<YourApp />
|
||||
</ThirdwebProvider>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Defining a Contract
|
||||
|
||||
You can define a contract using the [`getContract`](/references/typescript/v5/getContract) function.
|
||||
|
||||
```tsx
|
||||
import { getContract, defineChain } from "thirdweb";
|
||||
|
||||
const contract = await getContract({
|
||||
client,
|
||||
address: "0x...",
|
||||
chain: defineChain(8453),
|
||||
});
|
||||
```
|
||||
|
||||
### Read a Contract
|
||||
|
||||
You can read contract data using the [`useReadContract`](/references/typescript/v5/useReadContract) hook.
|
||||
|
||||
```tsx
|
||||
import { useReadContract } from "thirdweb/react";
|
||||
import { getContract, defineChain } from "thirdweb";
|
||||
|
||||
function YourApp() {
|
||||
const { data } = useReadContract({
|
||||
contract,
|
||||
method: "function allowance(address owner, address spender)",
|
||||
params: ["0x...", "0x..."],
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
{data?.toString()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Write to a Contract
|
||||
|
||||
You can write to a contract using [`prepareContractCall`](/references/typescript/v5/prepareContractCall) and the [`useSendTransaction`](/references/typescript/v5/useSendTransaction) hook.
|
||||
|
||||
```tsx
|
||||
import { useSendTransaction, useActiveAccount } from "thirdweb/react";
|
||||
|
||||
function YourApp() {
|
||||
const { mutate: sendTransaction, isPending, data } = useSendTransaction();
|
||||
|
||||
console.log("transaction hash", data?.transactionHash);
|
||||
|
||||
const onClick = () => {
|
||||
const transaction = prepareContractCall({
|
||||
contract,
|
||||
method: "function transfer(address to, uint256 amount)",
|
||||
params: ["0x...", "1000000000000000000"],
|
||||
});
|
||||
|
||||
// automatically uses the connected wallet as the sender
|
||||
sendTransaction(transaction);
|
||||
};
|
||||
|
||||
return (
|
||||
<button onClick={onClick}>
|
||||
Send Transaction
|
||||
</button>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
You can also use the [catalog of pre-built contract calls](/references/typescript/v5/functions#extensions) to easily prepare a transaction for standards like ERC20, ERC721, ERC1155, and more.
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="reactnative">
|
||||
### Installation
|
||||
|
||||
Install the thirdweb SDK in your React Native project:
|
||||
|
||||
<InstallTabs
|
||||
npm="npm i thirdweb"
|
||||
yarn="yarn add thirdweb"
|
||||
pnpm="pnpm i thirdweb"
|
||||
bun="bun i thirdweb"
|
||||
/>
|
||||
|
||||
|
||||
<Callout variant="info" title="Expo Go Support">
|
||||
You cannot use Expo Go with thirdweb because native modules are required.
|
||||
Use an Expo development build (`npx expo prebuild`) or React Native CLI app.
|
||||
</Callout>
|
||||
|
||||
### Create a Client
|
||||
|
||||
Create a client once and reuse it throughout your app:
|
||||
|
||||
```typescript
|
||||
import { createThirdwebClient } from "thirdweb";
|
||||
|
||||
export const client = createThirdwebClient({
|
||||
clientId: "YOUR_CLIENT_ID", // Get from your thirdweb dashboard
|
||||
});
|
||||
```
|
||||
|
||||
<Callout variant="info" title="Allowlist your Bundle ID">
|
||||
When creating your client ID on the thirdweb dashboard, allowlist your mobile app's bundle ID (e.g., com.yourcompany.app) for security.
|
||||
</Callout>
|
||||
|
||||
### Setup the Provider
|
||||
|
||||
Wrap your application with the ThirdwebProvider:
|
||||
|
||||
```tsx
|
||||
import { ThirdwebProvider } from "thirdweb/react";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<ThirdwebProvider>
|
||||
<YourApp />
|
||||
</ThirdwebProvider>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Defining a Contract
|
||||
|
||||
You can define a contract using the [`getContract`](/references/typescript/v5/getContract) function.
|
||||
|
||||
```tsx
|
||||
import { getContract, defineChain } from "thirdweb";
|
||||
|
||||
const contract = await getContract({
|
||||
client,
|
||||
address: "0x...",
|
||||
chain: defineChain(8453),
|
||||
});
|
||||
```
|
||||
|
||||
### Read a Contract
|
||||
|
||||
You can read contract data using the [`useReadContract`](/references/typescript/v5/useReadContract) hook.
|
||||
|
||||
```tsx
|
||||
import { useReadContract } from "thirdweb/react";
|
||||
import { getContract, defineChain } from "thirdweb";
|
||||
|
||||
const contract = await getContract({
|
||||
client,
|
||||
address: "0x...",
|
||||
chain: defineChain(8453),
|
||||
});
|
||||
|
||||
function YourApp() {
|
||||
const { data } = useReadContract({
|
||||
contract,
|
||||
method: "function allowance(address owner, address spender)",
|
||||
params: ["0x...", "0x..."],
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
{data?.toString()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Write to a Contract
|
||||
|
||||
You can write to a contract using [`prepareContractCall`](/references/typescript/v5/prepareContractCall) and the [`useSendTransaction`](/references/typescript/v5/useSendTransaction) hook.
|
||||
|
||||
```tsx
|
||||
import { useSendTransaction, useActiveAccount } from "thirdweb/react";
|
||||
|
||||
function YourApp() {
|
||||
const { mutate: sendTransaction, isPending, data } = useSendTransaction();
|
||||
|
||||
console.log("transaction hash", data?.transactionHash);
|
||||
|
||||
const onClick = () => {
|
||||
const transaction = prepareContractCall({
|
||||
contract,
|
||||
method: "function transfer(address to, uint256 amount)",
|
||||
params: ["0x...", "1000000000000000000"],
|
||||
});
|
||||
|
||||
// automatically uses the connected wallet as the sender
|
||||
sendTransaction(transaction);
|
||||
};
|
||||
|
||||
return (
|
||||
<button onClick={onClick}>
|
||||
Send Transaction
|
||||
</button>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
You can also use the [catalog of pre-built contract calls](/references/typescript/v5/functions#extensions) to easily prepare a transaction for standards like ERC20, ERC721, ERC1155, and more.
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="unity">
|
||||
### Installation
|
||||
|
||||
1. Download the latest [thirdweb Unity SDK](https://github.com/thirdweb-dev/unity-sdk/releases) (.unitypackage file)
|
||||
2. Import the package into your Unity project via Assets > Import Package > Custom Package
|
||||
|
||||
### Configure Client ID
|
||||
|
||||
After importing the SDK:
|
||||
|
||||
1. Go to Project Settings > Thirdweb
|
||||
2. Enter your Client ID from the thirdweb dashboard
|
||||
3. Allowlist your game's Bundle ID on the thirdweb dashboard for security
|
||||
|
||||
### Read a Contract
|
||||
|
||||
You can read contract data using the [`ThirdwebContract.Read`](/dotnet/contracts/read) method.
|
||||
|
||||
```csharp
|
||||
using Thirdweb;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class TransactionManager : MonoBehaviour
|
||||
{
|
||||
private ThirdwebSDK sdk;
|
||||
public Text walletAddressText;
|
||||
public Button sendButton;
|
||||
|
||||
void Start()
|
||||
{
|
||||
// Client ID is set in Project Settings > Thirdweb
|
||||
sdk = new ThirdwebSDK("ethereum"); // Or any supported chain
|
||||
sendButton.onClick.AddListener(ReadContract);
|
||||
}
|
||||
|
||||
public async void ReadContract()
|
||||
{
|
||||
try {
|
||||
var contract = await ThirdwebManager.Instance.GetContract(
|
||||
address: "contract-address",
|
||||
chainId: 1,
|
||||
abi: "optional-abi"
|
||||
);
|
||||
|
||||
// Send a transaction
|
||||
var data = await contract.Read(wallet, contract, "allowance", ownerAddress, spenderAddress);
|
||||
Debug.Log($"Contract data: {data}");
|
||||
}
|
||||
catch (System.Exception e) {
|
||||
Debug.LogError("Error sending transaction: " + e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Write to a Contract
|
||||
|
||||
You can write to a contract using the [`ThirdwebContract.Write`](/dotnet/contracts/write) method.
|
||||
|
||||
```csharp
|
||||
using Thirdweb;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class TransactionManager : MonoBehaviour
|
||||
{
|
||||
private ThirdwebSDK sdk;
|
||||
public Text walletAddressText;
|
||||
public Button sendButton;
|
||||
|
||||
void Start()
|
||||
{
|
||||
// Client ID is set in Project Settings > Thirdweb
|
||||
sdk = new ThirdwebSDK("ethereum"); // Or any supported chain
|
||||
sendButton.onClick.AddListener(SendTransaction);
|
||||
}
|
||||
|
||||
public async void SendTransaction()
|
||||
{
|
||||
try {
|
||||
var contract = await ThirdwebManager.Instance.GetContract(
|
||||
address: "contract-address",
|
||||
chainId: 1,
|
||||
abi: "optional-abi"
|
||||
);
|
||||
|
||||
// Send a transaction
|
||||
var receipt = await contract.Write(wallet, contract, "transfer", weiValue, toAddress, amount);
|
||||
Debug.Log($"Transaction receipt: {receipt}");
|
||||
}
|
||||
catch (System.Exception e) {
|
||||
Debug.LogError("Error sending transaction: " + e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="dotnet">
|
||||
### Installation
|
||||
|
||||
Install the thirdweb .NET SDK using NuGet:
|
||||
|
||||
```bash
|
||||
dotnet add package Thirdweb
|
||||
```
|
||||
|
||||
### Initialize the SDK
|
||||
|
||||
Create a client instance to connect with thirdweb services:
|
||||
|
||||
```csharp
|
||||
using Thirdweb;
|
||||
|
||||
// For client-side applications:
|
||||
var sdk = new ThirdwebSDK("ethereum", new ThirdwebSDK.Options
|
||||
{
|
||||
ClientId = "YOUR_CLIENT_ID" // From thirdweb dashboard
|
||||
});
|
||||
|
||||
// For server-side applications:
|
||||
// var sdk = new ThirdwebSDK("ethereum", new ThirdwebSDK.Options
|
||||
// {
|
||||
// SecretKey = Environment.GetEnvironmentVariable("THIRDWEB_SECRET_KEY")
|
||||
// });
|
||||
```
|
||||
|
||||
### Read a Contract
|
||||
|
||||
You can read contract data using the [`ThirdwebContract.Read`](/dotnet/contracts/read) method.
|
||||
|
||||
```csharp
|
||||
BigInteger chainId = 1; // Ethereum mainnet
|
||||
string contractAddress = "0x..."; // Your contract address
|
||||
var contract = await ThirdwebContract.Create(client, contractAddress, chainId);
|
||||
|
||||
var data = await contract.Read(wallet, contract, "allowance", ownerAddress, spenderAddress);
|
||||
Console.WriteLine($"Contract data: {data}");
|
||||
```
|
||||
|
||||
### Write to a Contract
|
||||
|
||||
```csharp
|
||||
BigInteger chainId = 1; // Ethereum mainnet
|
||||
string contractAddress = "0x..."; // Your contract address
|
||||
var contract = await ThirdwebContract.Create(client, contractAddress, chainId);
|
||||
|
||||
// The wallet that signs and sends the transaction
|
||||
var wallet = await PrivateKeyWallet.Create(client, "yourPrivateKeyHex");
|
||||
|
||||
// Assuming transfer takes an address and an amount as parameters
|
||||
string toAddress = "0x...";
|
||||
BigInteger amount = new BigInteger(1000); // The amount to transfer
|
||||
|
||||
// No ether is being sent in this non-payable transaction, so weiValue is 0
|
||||
BigInteger weiValue = BigInteger.Zero;
|
||||
|
||||
// Executing the transfer
|
||||
var receipt = await contract.Write(wallet, contract, "transfer", weiValue, toAddress, amount);
|
||||
Console.WriteLine($"Transaction receipt: {receipt}");
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="unreal">
|
||||
### Installation
|
||||
|
||||
1. Download the thirdweb Unreal Engine plugin from the [Unreal Engine Marketplace](https://www.unrealengine.com/marketplace/en-US/product/thirdweb)
|
||||
2. Add the plugin to your Unreal project
|
||||
3. Enable the plugin in your project settings
|
||||
|
||||
### Configure Client ID
|
||||
|
||||
1. Go to Edit > Project Settings > Thirdweb
|
||||
2. Enter your Client ID from the thirdweb dashboard
|
||||
3. Enter your Bundle ID (must match what was allowlisted on the thirdweb dashboard)
|
||||
|
||||
### Read and Write to a Contract
|
||||
|
||||
You can read and write to a contract using the [Engine Blueprint](/unreal-engine/blueprints/engine).
|
||||
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
||||
## Going further
|
||||
|
||||
- [Deploy Contracts](/contracts/deploy)
|
||||
- [Contract Events](/contracts/read)
|
||||
|
||||
## Explore Full API References
|
||||
|
||||
For comprehensive guides on implementing the full thirdweb SDK, explore our language-specific documentation:
|
||||
|
||||
<Grid>
|
||||
|
||||
<ArticleIconCard
|
||||
title="Deployment Tool"
|
||||
icon={ExternalLinkIcon}
|
||||
href="/contracts/deploy/overview"
|
||||
description="Securely deploy any smart contract."
|
||||
/>
|
||||
<ArticleIconCard
|
||||
title="Explore"
|
||||
icon={ExternalLinkIcon}
|
||||
href="/contracts/explore/overview"
|
||||
description="Audited and expansive library of contracts."
|
||||
/>
|
||||
|
||||
<ArticleIconCard
|
||||
title="Modular Contracts"
|
||||
icon={ExternalLinkIcon}
|
||||
href="/contracts/explore/overview"
|
||||
description="Build customizable smart contracts."
|
||||
/>
|
||||
|
||||
<SDKCard
|
||||
title="TypeScript"
|
||||
href="/references/typescript/v5"
|
||||
icon={TypeScriptIcon}
|
||||
/>
|
||||
<SDKCard title="React" href="/references/typescript/v5" icon={ReactIcon} />
|
||||
<SDKCard
|
||||
title="React Native"
|
||||
href="/references/typescript/v5"
|
||||
icon={ReactIcon}
|
||||
/>
|
||||
<SDKCard title="DotNet" href="/dotnet/getting-started" icon={DotNetIcon} />
|
||||
<SDKCard title="Unity" href="/unity/v5/getting-started" icon={UnityIcon} />
|
||||
<SDKCard
|
||||
title="Unreal Engine"
|
||||
href="/unreal-engine/getting-started"
|
||||
icon={UnrealEngineIcon}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<OpenSourceCard title="Contracts" href="https://github.com/thirdweb-dev/contracts" />
|
||||
|
||||
### With Contracts, you can:
|
||||
|
||||
- Easily deploy custom or pre-built contracts to [any EVM network](https://thirdweb.com/chainlist)
|
||||
- Create and publish contracts for your team or community to utilize with an easy-to-deploy interface
|
||||
- Create reusable contract components or modules to add to modular contracts to upgrade functionality
|
||||
- Manage contract functionality, upload NFTs, set distribution mechanisms, and more directly from the dashboard
|
||||
- Reduce development time by using an existing library of contracts with accompanying SDK functions and dashboard integrations to interact with contracts
|
||||
|
||||
### Templates
|
||||
|
||||
<ExpandableGrid>
|
||||
|
||||
<GithubTemplateCard
|
||||
title="Hardhat JavaScript Starter"
|
||||
href="https://github.com/thirdweb-example/hardhat-javascript-starter"
|
||||
/>
|
||||
|
||||
<GithubTemplateCard
|
||||
title="Hardhat TypeScript Starter"
|
||||
href="https://github.com/thirdweb-example/hardhat-typescript-starter"
|
||||
/>
|
||||
|
||||
<GithubTemplateCard
|
||||
title="Forge Starter"
|
||||
href="https://github.com/thirdweb-example/forge-starter"
|
||||
/>
|
||||
|
||||
<GithubTemplateCard
|
||||
title="Solidity Hello World"
|
||||
href="https://github.com/thirdweb-example/solidity-hello-world"
|
||||
/>
|
||||
|
||||
<GithubTemplateCard
|
||||
title="Smart Account Upgrades"
|
||||
href="https://github.com/thirdweb-example/smart-account-upgrades"
|
||||
/>
|
||||
|
||||
<GithubTemplateCard
|
||||
title="Tiered Loyalty Contract"
|
||||
href="https://github.com/thirdweb-example/tiered-loyalty-contract"
|
||||
/>
|
||||
|
||||
<GithubTemplateCard
|
||||
title="ERC-6551"
|
||||
href="https://github.com/thirdweb-example/erc-6551"
|
||||
/>
|
||||
|
||||
<GithubTemplateCard
|
||||
title="Anvil Local Node"
|
||||
href="https://github.com/thirdweb-example/anvil-local-node"
|
||||
/>
|
||||
|
||||
<GithubTemplateCard
|
||||
title="Soulbound Token"
|
||||
href="https://github.com/thirdweb-example/soulbound-token"
|
||||
/>
|
||||
|
||||
<GithubTemplateCard
|
||||
title="Onchain NFT Metadata"
|
||||
href="https://github.com/thirdweb-example/on-chain-nft-metadata"
|
||||
/>
|
||||
|
||||
<GithubTemplateCard
|
||||
title="ERC-721 NFT Collection with Deploy & Hardhat"
|
||||
href="https://github.com/thirdweb-example/erc721a-thirdweb-deploy"
|
||||
/>
|
||||
|
||||
<GithubTemplateCard
|
||||
title="Token Gated Account"
|
||||
href="https://github.com/thirdweb-example/token-gated-account"
|
||||
/>
|
||||
|
||||
</ExpandableGrid>
|
||||
|
||||
## Supported Chains
|
||||
Contracts is supported on every EVM compatible chain. To view the full list, visit [thirdweb chainlist](https://thirdweb.com/chainlist?service=contracts).
|
||||
|
||||
<DocImage src={SupportedChains} />
|
||||
|
||||
|
||||
@@ -1,847 +1,97 @@
|
||||
import { ZapIcon } from "lucide-react";
|
||||
import type { SideBar } from "@/components/Layouts/DocLayout";
|
||||
import { ContractModularContractIcon } from "@/icons";
|
||||
import {
|
||||
DotNetIcon,
|
||||
ReactIcon,
|
||||
TypeScriptIcon,
|
||||
UnityIcon,
|
||||
UnrealEngineIcon,
|
||||
} from "@/icons";
|
||||
|
||||
const prebuiltSlug = "/contracts/explore/pre-built-contracts";
|
||||
const prebuiltModular = "/contracts/explore/pre-built-modular";
|
||||
const modularContractsSlug = "/contracts/modular-contracts";
|
||||
const deploySlug = "/contracts/deploy";
|
||||
const publishSlug = "/contracts/publish";
|
||||
const designDocs = "/contracts/design-docs";
|
||||
const modulesContractsSlug = "/contracts/modular-contracts/module-contracts";
|
||||
const coreContractsSlug = "/contracts/modular-contracts/core-contracts";
|
||||
|
||||
// TODO: Deprecate links that start with the following slugs
|
||||
const buildSlug = "/contracts/build";
|
||||
const extensionsSlug = "/contracts/build/extensions";
|
||||
const baseContractsSlug = "/contracts/build/base-contracts";
|
||||
const slug = "/contracts";
|
||||
|
||||
export const sidebar: SideBar = {
|
||||
name: "Contracts",
|
||||
links: [
|
||||
{
|
||||
href: "/contracts",
|
||||
name: "Overview",
|
||||
href: slug,
|
||||
name: "Get Started",
|
||||
icon: <ZapIcon />,
|
||||
},
|
||||
{ separator: true },
|
||||
{
|
||||
isCollapsible: false,
|
||||
links: [
|
||||
{
|
||||
href: `${deploySlug}/overview`,
|
||||
name: "Overview",
|
||||
href: `${slug}/extensions`,
|
||||
name: "Use Extensions",
|
||||
},
|
||||
{
|
||||
href: `${deploySlug}/deploy-contract`,
|
||||
name: "Deploy Contract",
|
||||
href: `${slug}/generate`,
|
||||
name: "Generate Extensions",
|
||||
},
|
||||
{
|
||||
href: `${publishSlug}/publish-contract`,
|
||||
name: "Publish Contract",
|
||||
href: `${slug}/events`,
|
||||
name: "Listen to Events",
|
||||
},
|
||||
{
|
||||
href: `${deploySlug}/reference`,
|
||||
name: "CLI Reference",
|
||||
href: `${slug}/deploy`,
|
||||
name: "Deploy Contracts",
|
||||
},
|
||||
/**
|
||||
* TODO
|
||||
{
|
||||
href: `${slug}/encode`,
|
||||
name: "Encode Data",
|
||||
},
|
||||
{
|
||||
href: `${publishSlug}/publish-options`,
|
||||
name: "Publish Options",
|
||||
href: `${slug}/decode`,
|
||||
name: "Decode Data",
|
||||
},
|
||||
{
|
||||
href: `${slug}/fetch-abis`,
|
||||
name: "Fetch ABIs",
|
||||
},
|
||||
*/
|
||||
],
|
||||
name: "Deployment Tools",
|
||||
},
|
||||
// explore
|
||||
{
|
||||
isCollapsible: false,
|
||||
links: [
|
||||
{
|
||||
href: "/contracts/explore/overview",
|
||||
name: "Overview",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${prebuiltModular}/token`,
|
||||
name: "Token",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltModular}/token-drop`,
|
||||
name: "Token Drop",
|
||||
},
|
||||
],
|
||||
name: "ERC-20",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${prebuiltModular}/nft-collection`,
|
||||
name: "NFT Collection",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltModular}/nft-drop`,
|
||||
name: "NFT Drop",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltModular}/open-edition`,
|
||||
name: "Open Edition",
|
||||
},
|
||||
],
|
||||
name: "ERC-721",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${prebuiltModular}/edition`,
|
||||
name: "Edition",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltModular}/edition-drop`,
|
||||
name: "Edition Drop",
|
||||
},
|
||||
],
|
||||
name: "ERC-1155",
|
||||
},
|
||||
],
|
||||
name: "Pre-built Modular",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${prebuiltSlug}/token`,
|
||||
name: "Token",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/token-drop`,
|
||||
name: "Token Drop",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/stake-erc20`,
|
||||
name: "Stake ERC-20",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/airdrop-erc20`,
|
||||
name: "Airdrop ERC-20",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/airdrop-erc20-claimable`,
|
||||
name: "Airdrop ERC-20 (Claimable)",
|
||||
},
|
||||
],
|
||||
name: "ERC-20",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${prebuiltSlug}/nft-collection`,
|
||||
name: "NFT Collection",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/nft-drop`,
|
||||
name: "NFT Drop",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/loyalty-card`,
|
||||
name: "Loyalty Card",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/open-edition`,
|
||||
name: "Open Edition",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/stake-erc721`,
|
||||
name: "Stake ERC-721",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/airdrop-erc721`,
|
||||
name: "Airdrop ERC-721",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/airdrop-erc721-claimable`,
|
||||
name: "Airdrop ERC-721 (Claimable)",
|
||||
},
|
||||
],
|
||||
name: "ERC-721",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${prebuiltSlug}/edition`,
|
||||
name: "Edition",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/edition-drop`,
|
||||
name: "Edition Drop",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/stake-erc1155`,
|
||||
name: "Stake ERC-1155",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/airdrop-erc1155`,
|
||||
name: "Airdrop ERC-1155",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/airdrop-erc1155-claimable`,
|
||||
name: "Airdrop ERC-1155 (Claimable)",
|
||||
},
|
||||
],
|
||||
name: "ERC-1155",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${prebuiltSlug}/account-factory`,
|
||||
name: "Account Factory",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/managed-account-factory`,
|
||||
name: "Managed Account Factory",
|
||||
},
|
||||
],
|
||||
name: "ERC-4337",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${prebuiltSlug}/marketplace`,
|
||||
name: "Marketplace",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/multiwrap`,
|
||||
name: "Multiwrap",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/split`,
|
||||
name: "Split",
|
||||
},
|
||||
{
|
||||
href: `${prebuiltSlug}/vote`,
|
||||
name: "Vote",
|
||||
},
|
||||
],
|
||||
name: "MISC.",
|
||||
},
|
||||
],
|
||||
name: "Pre-built Standard",
|
||||
},
|
||||
],
|
||||
name: "Explore (Contract Library)",
|
||||
},
|
||||
|
||||
{ separator: true },
|
||||
// modular contracts
|
||||
{
|
||||
isCollapsible: false,
|
||||
links: [
|
||||
{
|
||||
href: `${modularContractsSlug}/overview`,
|
||||
name: "Overview",
|
||||
},
|
||||
{
|
||||
href: `${modularContractsSlug}/how-it-works`,
|
||||
name: "How it works",
|
||||
},
|
||||
{
|
||||
href: `${modularContractsSlug}/get-started`,
|
||||
links: [
|
||||
{
|
||||
href: `${modularContractsSlug}/get-started/create-core-contract`,
|
||||
name: "Create a Core Contract",
|
||||
},
|
||||
{
|
||||
href: `${modularContractsSlug}/get-started/create-module-contract`,
|
||||
name: "Create a Module Contract",
|
||||
},
|
||||
{
|
||||
href: `${modularContractsSlug}/get-started/deploy-modular-contract`,
|
||||
name: "Deploy a Modular Contract",
|
||||
},
|
||||
],
|
||||
name: "Get Started",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${modularContractsSlug}/tutorials/deploy-erc20-core`,
|
||||
name: "Deploy ERC-20 Core",
|
||||
},
|
||||
],
|
||||
name: "Tutorials",
|
||||
},
|
||||
// core contracts
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${coreContractsSlug}/erc-20`,
|
||||
name: "ERC-20",
|
||||
},
|
||||
{
|
||||
href: `${coreContractsSlug}/erc-721`,
|
||||
name: "ERC-721",
|
||||
},
|
||||
{
|
||||
href: `${coreContractsSlug}/erc-1155`,
|
||||
name: "ERC-1155",
|
||||
},
|
||||
],
|
||||
name: "Core Contracts",
|
||||
},
|
||||
// modules
|
||||
{
|
||||
links: [
|
||||
{
|
||||
links: [
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-20/minting/claimableERC20`,
|
||||
name: "ClaimableERC20",
|
||||
},
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-20/minting/mintableERC20`,
|
||||
name: "MintableERC20",
|
||||
},
|
||||
],
|
||||
name: "Minting",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-20/misc/transferableERC20`,
|
||||
name: "TransferableERC20",
|
||||
},
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-20/misc/creatorTokenERC20`,
|
||||
name: "CreatorTokenERC20",
|
||||
},
|
||||
],
|
||||
name: "Miscellaneous",
|
||||
},
|
||||
],
|
||||
name: "ERC-20",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-721/metadata/batchMetadataERC721`,
|
||||
name: "BatchMetadataERC721",
|
||||
},
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-721/metadata/openEditionMetadataERC721`,
|
||||
name: "OpenEditionMetadataERC721",
|
||||
},
|
||||
],
|
||||
name: "Metadata",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-721/minting/claimableERC721`,
|
||||
name: "ClaimableERC721",
|
||||
},
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-721/minting/mintableERC721`,
|
||||
name: "MintableERC721",
|
||||
},
|
||||
],
|
||||
name: "Minting",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-721/misc/royaltyERC721`,
|
||||
name: "RoyaltyERC721",
|
||||
},
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-721/misc/transferableERC721`,
|
||||
name: "TransferableERC721",
|
||||
},
|
||||
],
|
||||
name: "Miscellaneous",
|
||||
},
|
||||
],
|
||||
name: "ERC-721",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-1155/metadata/batchMetadataERC1155`,
|
||||
name: "BatchMetadataERC1155",
|
||||
},
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-1155/metadata/openEditionMetadataERC1155`,
|
||||
name: "OpenEditionMetadataERC1155",
|
||||
},
|
||||
],
|
||||
name: "Metadata",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-1155/minting/claimableERC1155`,
|
||||
name: "ClaimableERC1155",
|
||||
},
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-1155/minting/mintableERC1155`,
|
||||
name: "MintableERC1155",
|
||||
},
|
||||
],
|
||||
name: "Minting",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-1155/misc/royaltyERC1155`,
|
||||
name: "RoyaltyERC1155",
|
||||
},
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-1155/misc/transferableERC1155`,
|
||||
name: "TransferableERC1155",
|
||||
},
|
||||
{
|
||||
href: `${modulesContractsSlug}/erc-1155/misc/sequentialTokenIdERC1155`,
|
||||
name: "SequentialTokenIdERC1155",
|
||||
},
|
||||
],
|
||||
name: "Miscellaneous",
|
||||
},
|
||||
],
|
||||
name: "ERC-1155",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${modulesContractsSlug}/cross-chain/agglayer`,
|
||||
name: "Agglayer",
|
||||
},
|
||||
],
|
||||
name: "Cross-Chain",
|
||||
},
|
||||
],
|
||||
name: "Module Contracts",
|
||||
},
|
||||
],
|
||||
name: "Modular Contract Framework",
|
||||
},
|
||||
|
||||
{ separator: true },
|
||||
// build
|
||||
{
|
||||
icon: <ContractModularContractIcon />,
|
||||
isCollapsible: false,
|
||||
links: [
|
||||
{
|
||||
href: `${buildSlug}/overview`,
|
||||
name: "Overview",
|
||||
},
|
||||
{
|
||||
href: `${buildSlug}/get-started`,
|
||||
name: "Get Started",
|
||||
},
|
||||
// modular contracts
|
||||
{
|
||||
href: `${buildSlug}/modular-contracts`,
|
||||
name: "Modular Contracts",
|
||||
},
|
||||
// base contracts
|
||||
{
|
||||
href: `${baseContractsSlug}`,
|
||||
links: [
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-20/base`,
|
||||
name: "Base",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-20/drop`,
|
||||
name: "Drop",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-20/drop-vote`,
|
||||
name: "Drop Vote",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-20/signature-mint`,
|
||||
name: "Signature Mint",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-20/signature-mint-vote`,
|
||||
name: "Signature Mint Vote",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-20/vote`,
|
||||
name: "Vote",
|
||||
},
|
||||
],
|
||||
name: "ERC-20",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-721/base`,
|
||||
name: "Base",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-721/delayed-reveal`,
|
||||
name: "Delayed Reveal",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-721/drop`,
|
||||
name: "Drop",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-721/lazy-mint`,
|
||||
name: "Lazy Mint",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-721/signature-mint`,
|
||||
name: "Signature Mint",
|
||||
},
|
||||
],
|
||||
name: "ERC-721",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-1155/base`,
|
||||
name: "Base",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-1155/delayed-reveal`,
|
||||
name: "Delayed Reveal",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-1155/drop`,
|
||||
name: "Drop",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-1155/lazy-mint`,
|
||||
name: "Lazy Mint",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-1155/signature-mint`,
|
||||
name: "Signature Mint",
|
||||
},
|
||||
],
|
||||
name: "ERC-1155",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-4337`,
|
||||
links: [
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-4337/account`,
|
||||
name: "Account",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-4337/account-factory`,
|
||||
name: "Account Factory",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-4337/managed-account`,
|
||||
name: "Managed Account",
|
||||
},
|
||||
{
|
||||
href: `${baseContractsSlug}/erc-4337/managed-account-factory`,
|
||||
name: "Managed Account Factory",
|
||||
},
|
||||
],
|
||||
name: "ERC-4337",
|
||||
},
|
||||
],
|
||||
name: "Base Contracts",
|
||||
},
|
||||
// extensions
|
||||
{
|
||||
href: `${extensionsSlug}`,
|
||||
links: [
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${extensionsSlug}/general/BatchMintMetadata`,
|
||||
name: "BatchMintMetadata",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/general/ContractMetadata`,
|
||||
name: "ContractMetadata",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/general/DelayedReveal`,
|
||||
name: "DelayedReveal",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/general/Drop`,
|
||||
name: "Drop",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/general/DropSinglePhase`,
|
||||
name: "DropSinglePhase",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/general/LazyMint`,
|
||||
name: "LazyMint",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/general/Multicall`,
|
||||
name: "Multicall",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/general/Ownable`,
|
||||
name: "Ownable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/general/Permissions`,
|
||||
name: "Permissions",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/general/PermissionsEnumerable`,
|
||||
name: "PermissionsEnumerable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/general/PlatformFee`,
|
||||
name: "PlatformFee",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/general/PrimarySale`,
|
||||
name: "PrimarySale",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/general/Royalty`,
|
||||
name: "Royalty",
|
||||
},
|
||||
],
|
||||
name: "General",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${extensionsSlug}/erc-20/ERC20`,
|
||||
name: "ERC20",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-20/ERC20BatchMintable`,
|
||||
name: "ERC20BatchMintable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-20/ERC20Burnable`,
|
||||
name: "ERC20Burnable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-20/ERC20ClaimConditions`,
|
||||
name: "ERC20ClaimConditions",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-20/ERC20Mintable`,
|
||||
name: "ERC20Mintable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-20/ERC20Permit`,
|
||||
name: "ERC20Permit",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-20/ERC20SignatureMint`,
|
||||
name: "ERC20SignatureMint",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-20/ERC20Staking`,
|
||||
name: "ERC20Staking",
|
||||
},
|
||||
],
|
||||
name: "ERC-20",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${extensionsSlug}/erc-721/ERC721`,
|
||||
name: "ERC721",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-721/ERC721BatchMintable`,
|
||||
name: "ERC721BatchMintable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-721/ERC721Burnable`,
|
||||
name: "ERC721Burnable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-721/ERC721ClaimConditions`,
|
||||
name: "ERC721ClaimConditions",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-721/ERC721ClaimCustom`,
|
||||
name: "ERC721ClaimCustom",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-721/ERC721ClaimPhases`,
|
||||
name: "ERC721ClaimPhases",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-721/ERC721Claimable`,
|
||||
name: "ERC721Claimable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-721/ERC721Enumerable`,
|
||||
name: "ERC721Enumerable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-721/ERC721Mintable`,
|
||||
name: "ERC721Mintable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-721/ERC721Revealable`,
|
||||
name: "ERC721Revealable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-721/ERC721SignatureMint`,
|
||||
name: "ERC721SignatureMint",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-721/ERC721Staking`,
|
||||
name: "ERC721Staking",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-721/ERC721Supply`,
|
||||
name: "ERC721Supply",
|
||||
},
|
||||
],
|
||||
name: "ERC-721",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${extensionsSlug}/erc-1155/ERC1155`,
|
||||
name: "ERC1155",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-1155/ERC1155BatchMintable`,
|
||||
name: "ERC1155BatchMintable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-1155/ERC1155Burnable`,
|
||||
name: "ERC1155Burnable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-1155/ERC1155ClaimConditions`,
|
||||
name: "ERC1155ClaimConditions",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-1155/ERC1155ClaimCustom`,
|
||||
name: "ERC1155ClaimCustom",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-1155/ERC1155ClaimPhases`,
|
||||
name: "ERC1155ClaimPhases",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-1155/ERC1155Claimable`,
|
||||
name: "ERC1155Claimable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-1155/ERC1155Drop`,
|
||||
name: "ERC1155Drop",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-1155/ERC1155DropSinglePhase`,
|
||||
name: "ERC1155DropSinglePhase",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-1155/ERC1155Enumerable`,
|
||||
name: "ERC1155Enumerable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-1155/ERC1155Mintable`,
|
||||
name: "ERC1155Mintable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-1155/ERC1155Revealable`,
|
||||
name: "ERC1155Revealable",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-1155/ERC1155SignatureMint`,
|
||||
name: "ERC1155SignatureMint",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-1155/ERC1155Staking`,
|
||||
name: "ERC1155Staking",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-1155/ERC1155Supply`,
|
||||
name: "ERC1155Supply",
|
||||
},
|
||||
],
|
||||
name: "ERC-1155",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${extensionsSlug}/erc-4337/SmartWallet`,
|
||||
name: "SmartWallet",
|
||||
},
|
||||
{
|
||||
href: `${extensionsSlug}/erc-4337/SmartWalletFactory`,
|
||||
name: "SmartWalletFactory",
|
||||
},
|
||||
],
|
||||
name: "ERC-4337",
|
||||
},
|
||||
],
|
||||
name: "Extensions",
|
||||
},
|
||||
// stylus
|
||||
{
|
||||
href: `${buildSlug}/stylus`,
|
||||
name: "Arbitrum Stylus",
|
||||
},
|
||||
],
|
||||
name: "Build",
|
||||
name: "Guides",
|
||||
},
|
||||
{ separator: true },
|
||||
// resources
|
||||
{
|
||||
isCollapsible: false,
|
||||
links: [
|
||||
{
|
||||
href: "/contracts/faq",
|
||||
name: "FAQs",
|
||||
href: "/references/typescript/v5/functions#transactions",
|
||||
icon: <TypeScriptIcon />,
|
||||
name: "TypeScript",
|
||||
},
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: `${designDocs}/modular-contracts`,
|
||||
name: "Modular Contracts",
|
||||
},
|
||||
{
|
||||
href: `${designDocs}/drop`,
|
||||
name: "Drop",
|
||||
},
|
||||
{
|
||||
href: `${designDocs}/marketplace`,
|
||||
name: "Marketplace",
|
||||
},
|
||||
{
|
||||
href: `${designDocs}/multiwrap`,
|
||||
name: "Multiwrap",
|
||||
},
|
||||
{
|
||||
href: `${designDocs}/pack`,
|
||||
name: "Pack",
|
||||
},
|
||||
{
|
||||
href: `${designDocs}/signature-mint`,
|
||||
name: "Signature Mint",
|
||||
},
|
||||
],
|
||||
name: "Design Docs",
|
||||
href: "/references/typescript/v5/hooks#transactions",
|
||||
icon: <ReactIcon />,
|
||||
name: "React",
|
||||
},
|
||||
{
|
||||
href: "/references/typescript/v5/hooks#transactions",
|
||||
icon: <ReactIcon />,
|
||||
name: "React Native",
|
||||
},
|
||||
{
|
||||
href: "/dotnet",
|
||||
icon: <DotNetIcon />,
|
||||
name: "Dotnet",
|
||||
},
|
||||
{
|
||||
href: "/unity",
|
||||
icon: <UnityIcon />,
|
||||
name: "Unity",
|
||||
},
|
||||
{
|
||||
href: "/unreal-engine",
|
||||
icon: <UnrealEngineIcon />,
|
||||
name: "Unreal Engine",
|
||||
},
|
||||
],
|
||||
name: "Resources",
|
||||
name: "API References",
|
||||
},
|
||||
],
|
||||
name: "Contracts",
|
||||
};
|
||||
|
||||
@@ -57,7 +57,7 @@ The relayer will be assigned a URL in this format: `https://<engine_url>/relayer
|
||||
|
||||
## Submit a meta transaction from your app frontend
|
||||
|
||||
Use the [Connect SDK](/react) to prompt the user to sign transactions and send it this relayer.
|
||||
Use the [TypeScript SDK]](/react) to prompt the user to sign transactions and send it this relayer.
|
||||
|
||||
First wrap your app with `<ThirdwebProvider>`:
|
||||
|
||||
|
||||
@@ -108,6 +108,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.no-scrollbar {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
code span {
|
||||
color: var(--code-light-color);
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ export const sidebar: SideBar = {
|
||||
{
|
||||
links: [
|
||||
{
|
||||
href: "/connect",
|
||||
name: "Connect SDK",
|
||||
href: "/wallets",
|
||||
name: "TypeScript SDK",
|
||||
},
|
||||
{
|
||||
href: `${storageSlug}/how-to-use-storage/upload-files-to-ipfs`,
|
||||
|
||||
@@ -53,7 +53,7 @@ export default function RootLayout({
|
||||
<div className="relative flex min-h-screen flex-col">
|
||||
<StickyTopContainer>
|
||||
{/* <Banner
|
||||
href="https://thirdweb.com/connect/universal-bridge"
|
||||
href="https://thirdweb.com/payments"
|
||||
text="Let users pay with whatever they have without leaving your app"
|
||||
/> */}
|
||||
<Header />
|
||||
|
||||
@@ -105,7 +105,7 @@ async function handleNebulaResponse(response) {
|
||||
secretKey: process.env.THIRDWEB_SECRET_KEY,
|
||||
});
|
||||
|
||||
// You can use any wallet- see https://portal.thirdweb.com/connect/external-wallets
|
||||
// You can use any wallet- see https://portal.thirdweb.com/wallets/external-wallets
|
||||
const account = await generateAccount({ client });
|
||||
|
||||
if (response.actions && response.actions.length > 0) {
|
||||
|
||||
+122
-117
@@ -1,10 +1,11 @@
|
||||
import { MessageCircleIcon, WebhookIcon } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { Grid, Heading, SDKCard } from "@/components/Document";
|
||||
import { Heading } from "@/components/Document";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
DotNetIcon,
|
||||
ExternalLinkIcon,
|
||||
ReactIcon,
|
||||
TypeScriptIcon,
|
||||
UnityIcon,
|
||||
@@ -15,14 +16,13 @@ import { ConnectIcon } from "../icons/products/ConnectIcon";
|
||||
import { EngineIcon } from "../icons/products/EngineIcon";
|
||||
import { InsightIcon } from "../icons/products/InsightIcon";
|
||||
import { PlaygroundIcon } from "../icons/products/PlaygroundIcon";
|
||||
import { cn } from "../lib/utils";
|
||||
import DocsHeroDark from "./_images/docs-hero-dark.png";
|
||||
import DocsHeroLight from "./_images/docs-hero-light.png";
|
||||
export default function Page() {
|
||||
return (
|
||||
<main className="container max-w-[900px] grow pb-20" data-noindex>
|
||||
<main className="container max-w-5xl grow pb-20" data-noindex>
|
||||
<Hero />
|
||||
<div className="grid grid-cols-1 gap-8">
|
||||
<div className="space-y-8">
|
||||
<PlaygroundSection />
|
||||
<LearningResourcesSection />
|
||||
<ReferenceSection />
|
||||
@@ -33,7 +33,7 @@ export default function Page() {
|
||||
|
||||
function Hero() {
|
||||
return (
|
||||
<section className="grid gap-4 py-14 lg:grid-cols-2 lg:py-0">
|
||||
<section className="grid gap-4 py-14 lg:grid-cols-[1fr_420px] lg:py-0">
|
||||
{/* Left */}
|
||||
<div className="flex flex-col justify-center">
|
||||
<div>
|
||||
@@ -43,13 +43,14 @@ function Hero() {
|
||||
<p className="mb-8 max-w-md text-lg text-muted-foreground leading-normal">
|
||||
Development framework for building onchain apps, games, and agents.
|
||||
</p>
|
||||
|
||||
<Link href="/chat">
|
||||
<Button className="flex items-center gap-2">
|
||||
<MessageCircleIcon className="size-4" />
|
||||
Ask AI
|
||||
<div className="flex">
|
||||
<Button className="flex items-center gap-2" asChild>
|
||||
<Link href="/chat">
|
||||
<MessageCircleIcon className="size-4" />
|
||||
Ask AI
|
||||
</Link>
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -79,86 +80,67 @@ function PlaygroundSection() {
|
||||
|
||||
function ReferenceSection() {
|
||||
return (
|
||||
<section>
|
||||
<SectionTitle anchorId="reference" title="API Reference" />
|
||||
<SectionTitle
|
||||
anchorId="client"
|
||||
className="text-muted-foreground"
|
||||
level={4}
|
||||
title="Client libraries"
|
||||
/>
|
||||
<Grid>
|
||||
<SDKCard
|
||||
href="/references/typescript/v5"
|
||||
icon={TypeScriptIcon}
|
||||
title="TypeScript"
|
||||
/>
|
||||
<SDKCard
|
||||
href="/references/typescript/v5"
|
||||
icon={ReactIcon}
|
||||
title="React"
|
||||
/>
|
||||
<SDKCard
|
||||
href="/references/typescript/v5"
|
||||
icon={ReactIcon}
|
||||
title="React Native"
|
||||
/>
|
||||
<SDKCard href="/dotnet" icon={DotNetIcon} title="DotNet" />
|
||||
<SDKCard href="/unity" icon={UnityIcon} title="Unity" />
|
||||
<SDKCard
|
||||
href="/unreal-engine"
|
||||
icon={UnrealEngineIcon}
|
||||
title="Unreal Engine"
|
||||
/>
|
||||
</Grid>
|
||||
<SectionTitle
|
||||
anchorId="backend"
|
||||
className="text-muted-foreground"
|
||||
level={4}
|
||||
title="Backend APIs"
|
||||
/>
|
||||
<Grid>
|
||||
<SDKCard
|
||||
href="https://engine.thirdweb.com/reference"
|
||||
icon={EngineIcon}
|
||||
iconClassName="text-muted-foreground"
|
||||
isExternal
|
||||
title="Engine"
|
||||
/>
|
||||
<SDKCard
|
||||
href="https://insight.thirdweb.com/reference"
|
||||
icon={InsightIcon}
|
||||
iconClassName="text-muted-foreground"
|
||||
isExternal
|
||||
title="Insight"
|
||||
/>
|
||||
<SDKCard
|
||||
href="https://bridge.thirdweb.com/reference"
|
||||
icon={BridgeIcon}
|
||||
iconClassName="text-muted-foreground"
|
||||
isExternal
|
||||
title="Payments"
|
||||
/>
|
||||
<SDKCard
|
||||
href="/connect/wallet/get-users"
|
||||
icon={ConnectIcon} // TODO: actual openAPI docs
|
||||
iconClassName="text-muted-foreground"
|
||||
title="Wallets"
|
||||
/>
|
||||
<SDKCard
|
||||
href="/connect/account-abstraction/api"
|
||||
icon={ConnectIcon} // TODO: actual openAPI docs
|
||||
iconClassName="text-muted-foreground"
|
||||
title="Bundler"
|
||||
/>
|
||||
<SDKCard
|
||||
href="/webhooks"
|
||||
icon={WebhookIcon}
|
||||
iconClassName="text-muted-foreground"
|
||||
title="Webhooks"
|
||||
/>
|
||||
</Grid>
|
||||
</section>
|
||||
<>
|
||||
<section>
|
||||
<SectionTitle anchorId="client" title="Client libraries" />
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
<SDKCard
|
||||
href="/references/typescript/v5"
|
||||
icon={TypeScriptIcon}
|
||||
title="TypeScript"
|
||||
/>
|
||||
<SDKCard
|
||||
href="/references/typescript/v5"
|
||||
icon={ReactIcon}
|
||||
title="React"
|
||||
/>
|
||||
<SDKCard
|
||||
href="/references/typescript/v5"
|
||||
icon={ReactIcon}
|
||||
title="React Native"
|
||||
/>
|
||||
<SDKCard href="/dotnet" icon={DotNetIcon} title="DotNet" />
|
||||
<SDKCard href="/unity" icon={UnityIcon} title="Unity" />
|
||||
<SDKCard
|
||||
href="/unreal-engine"
|
||||
icon={UnrealEngineIcon}
|
||||
title="Unreal Engine"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<SectionTitle anchorId="backend" title="Backend APIs" />
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
<SDKCard
|
||||
href="https://engine.thirdweb.com/reference"
|
||||
icon={EngineIcon}
|
||||
title="Engine"
|
||||
/>
|
||||
<SDKCard
|
||||
href="https://insight.thirdweb.com/reference"
|
||||
icon={InsightIcon}
|
||||
title="Insight"
|
||||
/>
|
||||
<SDKCard
|
||||
href="https://bridge.thirdweb.com/reference"
|
||||
icon={BridgeIcon}
|
||||
title="Payments"
|
||||
/>
|
||||
<SDKCard
|
||||
href="/wallets/get-users"
|
||||
icon={ConnectIcon} // TODO: actual openAPI docs
|
||||
title="Wallets"
|
||||
/>
|
||||
<SDKCard
|
||||
href="/bundler"
|
||||
icon={ConnectIcon} // TODO: actual openAPI docs
|
||||
title="Bundler"
|
||||
/>
|
||||
<SDKCard href="/webhooks" icon={WebhookIcon} title="Webhooks" />
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -166,7 +148,7 @@ function LearningResourcesSection() {
|
||||
return (
|
||||
<section>
|
||||
<SectionTitle anchorId="learning" title="Documentation" />
|
||||
<Grid className="md:grid-cols-1 lg:grid-cols-3">
|
||||
<div className="grid gap-4 md:grid-cols-1 lg:grid-cols-3">
|
||||
<ArticleCardIndex
|
||||
description="Create and manage crypto wallets"
|
||||
href="/wallets"
|
||||
@@ -203,24 +185,14 @@ function LearningResourcesSection() {
|
||||
icon={ConnectIcon}
|
||||
title="Vault"
|
||||
/>
|
||||
</Grid>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function SectionTitle(props: {
|
||||
title: string;
|
||||
anchorId: string;
|
||||
level?: number;
|
||||
className?: string;
|
||||
}) {
|
||||
function SectionTitle(props: { title: string; anchorId: string }) {
|
||||
return (
|
||||
<Heading
|
||||
anchorClassName="mb-4 mt-0"
|
||||
anchorId={props.anchorId}
|
||||
className={cn(props.className)}
|
||||
level={props.level || 2}
|
||||
>
|
||||
<Heading anchorId={props.anchorId} anchorClassName="mb-2" level={2}>
|
||||
{props.title}
|
||||
</Heading>
|
||||
);
|
||||
@@ -233,22 +205,55 @@ function ArticleCardIndex(props: {
|
||||
title: string;
|
||||
description: string;
|
||||
href: string;
|
||||
icon?: React.FC<{ className?: string }>;
|
||||
icon: React.FC<{ className?: string }>;
|
||||
external?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<Link
|
||||
className="flex items-center gap-4 rounded-lg border bg-card p-4 transition-colors hover:border-active-border"
|
||||
href={props.href}
|
||||
target={props.external ? "_blank" : undefined}
|
||||
>
|
||||
<div className="flex items-start gap-3">
|
||||
{props.icon && <props.icon className="text-foreground size-6" />}
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<h3 className="font-semibold text-foreground">{props.title}</h3>
|
||||
<p className="text-sm text-muted-foreground">{props.description}</p>
|
||||
<div className="rounded-lg border bg-card p-4 hover:border-active-border relative">
|
||||
<div className="flex mb-3">
|
||||
<div className="p-2 rounded-full border bg-background">
|
||||
<props.icon className="size-5 text-muted-foreground" />
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
<h3 className="mb-0.5 font-medium text-lg tracking-tight">
|
||||
<Link
|
||||
className="before:absolute before:inset-0"
|
||||
href={props.href}
|
||||
target={props.external ? "_blank" : undefined}
|
||||
>
|
||||
{props.title}
|
||||
</Link>
|
||||
</h3>
|
||||
<p className="text-sm text-muted-foreground">{props.description}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SDKCard(props: {
|
||||
title: string;
|
||||
href: string;
|
||||
icon: React.FC<{ className?: string }>;
|
||||
}) {
|
||||
return (
|
||||
<div className="relative flex items-center gap-3 rounded-lg border bg-card p-4 transition-colors hover:border-active-border text-foreground/80 hover:text-foreground">
|
||||
<div className="p-2 rounded-full border bg-background">
|
||||
<props.icon className="size-4 shrink-0" />
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<h3 className="font-medium text-base text-foreground mb-0.5">
|
||||
<Link
|
||||
href={props.href}
|
||||
target={props.href.includes("http") ? "_blank" : undefined}
|
||||
className="before:absolute before:inset-0"
|
||||
>
|
||||
{props.title}
|
||||
</Link>
|
||||
</h3>
|
||||
<p className="inline-flex items-center gap-1 text-muted-foreground text-xs">
|
||||
View docs
|
||||
<ExternalLinkIcon className="size-3.5 shrink-0 text-muted-foreground/50" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ Yes, Payments is designed to be agnostic to wallet infrastructure. You can use i
|
||||
</Details>
|
||||
|
||||
<Details summary="Does Payments support Apple Pay or Google Pay?">
|
||||
Apple Pay and Google Pay are supported through the onramp providers depending on region. Coinbase, Stripe, and Transak currently support Apple Pay. Transak supports Google Pay. [Learn more about the supported onramp providers.](/connect/pay/onramp-providers).
|
||||
Apple Pay and Google Pay are supported through the onramp providers depending on region. Coinbase, Stripe, and Transak currently support Apple Pay. Transak supports Google Pay.
|
||||
</Details>
|
||||
|
||||
<Details summary="What are the KYC requirements?">
|
||||
|
||||
@@ -27,7 +27,7 @@ In this guide, we'll show you how to purchase 10 USDC on Optimism in Typescript.
|
||||
---
|
||||
|
||||
<Steps>
|
||||
<Step title='Install the Connect SDK'>
|
||||
<Step title='Install the TypeScript SDK'>
|
||||
<InstallTabs
|
||||
npm="npm i thirdweb"
|
||||
yarn="yarn add thirdweb"
|
||||
@@ -35,7 +35,7 @@ In this guide, we'll show you how to purchase 10 USDC on Optimism in Typescript.
|
||||
/>
|
||||
<Step title='Get Your Client ID'>
|
||||
|
||||
Log in to the [thirdweb dashboard](https://thirdweb.com/team). Click on Create New > Project to get your **Client ID**. You'll need your Client ID to interact with the Connect SDK.
|
||||
Log in to the [thirdweb dashboard](https://thirdweb.com/team). Click on Create New > Project to get your **Client ID**. You'll need your Client ID to interact with the TypeScript SDK.
|
||||
|
||||
</Step>
|
||||
</Step>
|
||||
|
||||
@@ -21,8 +21,8 @@ import {
|
||||
|
||||
export const metadata = createMetadata({
|
||||
image: {
|
||||
title: "Payments",
|
||||
icon: "pay",
|
||||
title: "Custom Payment Data",
|
||||
icon: "payments",
|
||||
},
|
||||
title: "Custom Payment Data",
|
||||
description: "Pass custom app data to payments to be included on webhooks, payment history, and more.",
|
||||
@@ -92,7 +92,7 @@ Associate user IDs, custom payment IDs, order details, and more with any payment
|
||||
amount="0.1"
|
||||
purchaseData={{
|
||||
userId: "user-123",
|
||||
orderId: "order-456",
|
||||
orderId: "order-456",
|
||||
productType: "wallet-funding",
|
||||
metadata: {
|
||||
source: "app",
|
||||
@@ -195,7 +195,7 @@ To connect with other auth strategies, use external wallets, or sponsor gas for
|
||||
|
||||
- [Buy.prepare](/references/typescript/v5/buy/prepare)
|
||||
- [Sell.prepare](/references/typescript/v5/sell/prepare)
|
||||
- [BuyWidget](/references/typescript/v5/buywidget)
|
||||
- [CheckoutWidget](/references/typescript/v5/checkoutwidget)
|
||||
- [TransactionWidget](/references/typescript/v5/transactionwidget)
|
||||
- [BuyWidget](/references/typescript/v5/widgets/BuyWidget)
|
||||
- [CheckoutWidget](/references/typescript/v5/widgets/CheckoutWidget)
|
||||
- [TransactionWidget](/references/typescript/v5/widgets/TransactionWidget)
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
import { createMetadata, Details } from "@doc";
|
||||
|
||||
export const metadata = createMetadata({
|
||||
image: {
|
||||
title: "thirdweb Payments - FAQs",
|
||||
icon: "thirdweb",
|
||||
},
|
||||
title: "thirdweb Payments - FAQs - thirdweb",
|
||||
description: "thirdweb Payments - Frequently Asked Questions",
|
||||
});
|
||||
|
||||
# FAQs
|
||||
|
||||
<Details summary="What are the fees for Buy With Fiat?">
|
||||
thirdweb does not charge any fees for buy with fiat. Any fees on onramping are based on the onramp provider.
|
||||
</Details>
|
||||
|
||||
<Details summary="What are the fees for Buy With Crypto?">
|
||||
For buying with crypto or swap fees, thirdweb charges a 0.3% protocol fee. Developers may monetize their application by charging additional fees on swap transactions. To set a fee in your project page, navigate to Payments > Settings to set this fee.
|
||||
</Details>
|
||||
|
||||
<Details summary="What does the term “network fees” refer to?">
|
||||
Network fees, also referred to as miner fees, are paid to the miner for processing crypto transactions and securing the respective network. These fees do not go to thirdweb.
|
||||
</Details>
|
||||
|
||||
<Details summary="What does Payments use to operate under the hood?">
|
||||
Payments is an asset router that combines thirdweb's own onchain infrastructure with existing bridging and swapping protocols to find the optimal route for any given transaction.
|
||||
This can include intents, native bridges, third party bridges, cross-chain messaging protocols, thirdweb's custom bridges, and more. All routes are monitored and planned continuously for
|
||||
health, price, and speed to guarantee the best path every time.
|
||||
</Details>
|
||||
|
||||
<Details summary="How can I support a token on Payments?">
|
||||
Payments is able to support most token that meet the following criteria:
|
||||
|
||||
- The token must have sufficient liquidity
|
||||
- The token must be on a [supported Payments Chain](https://thirdweb.com/chainlist?service=pay).
|
||||
|
||||
To request support for a token, please visit the Payments tab in your project dashboard > Settings > "Don't see your token listed?" component and fill out the chain and token address information.
|
||||
|
||||
Payments will automatically kick off the token route discovery process. Please check back the Payments modal after 20-40 minutes for the requested token.
|
||||
</Details>
|
||||
|
||||
<Details summary="Am I able to use Payments with other wallet infrastructure providers?">
|
||||
Yes, Payments is designed to be agnostic to wallet infrastructure. You can use it with any wallet service.
|
||||
</Details>
|
||||
|
||||
<Details summary="Does Payments support Apple Pay or Google Pay?">
|
||||
Apple Pay and Google Pay are supported through the onramp providers depending on region. Coinbase, Stripe, and Transak currently support Apple Pay. Transak supports Google Pay.
|
||||
</Details>
|
||||
|
||||
<Details summary="What are the KYC requirements?">
|
||||
Onramp options all require minimal KYC. This is done to comply with local regulations and to ensure the safety of our users.
|
||||
Please note: onramping with Coinbase does not require KYC for a purchase below $500 with debit card.
|
||||
</Details>
|
||||
|
||||
<Details summary="What are your transaction limits for Buy With Fiat?">
|
||||
We currently require a $1 minimum purchase for both stablecoin and non-stablecoin purchases through Buy With Fiat.
|
||||
|
||||
Our transaction maximum starts from $1500 per week for new users and can increase over time to $10,000 per week.
|
||||
</Details>
|
||||
|
||||
<Details summary="What countries does Buy With Fiat support?">
|
||||
**Buy With Fiat** is available 160+ countries. The following countries are _UNSUPPORTED_:
|
||||
|
||||
- Afghanistan
|
||||
- Africa (All Countries)
|
||||
- Belarus
|
||||
- Bolivia
|
||||
- China
|
||||
- Cuba
|
||||
- Colombia
|
||||
- Haiti
|
||||
- Honduras
|
||||
- Iran
|
||||
- Iraq
|
||||
- Latvia
|
||||
- Lebanon
|
||||
- Myanmar
|
||||
- Pakistan
|
||||
- Qatar
|
||||
- Russia
|
||||
- Ukraine
|
||||
- United Arab Emirates
|
||||
- Venezuela
|
||||
- Yemen
|
||||
|
||||
All United States are supported, excluding Hawaii.
|
||||
</Details>
|
||||
|
||||
<Details summary="Does thirdweb offer direct onramping to tokens through Buy With Fiat?">
|
||||
We offer direct onramping **internationally** to the following tokens:
|
||||
|
||||
- Mainnet (Ethereum)
|
||||
- Avalanche
|
||||
- Polygon
|
||||
|
||||
We offer direct onramping to the following tokens in the **US only**:
|
||||
|
||||
- ETH (Base)\*
|
||||
- USDC (Ethereum)
|
||||
- USDC (Polygon)\*
|
||||
- USDC (Avalanche)\*
|
||||
- USDC (Base)\*
|
||||
|
||||
All other tokens will require an additional Buy With Crypto step.
|
||||
|
||||
\* Not available in New York or the EU.
|
||||
</Details>
|
||||
|
||||
<Details summary="How does KYC work with Buy With Fiat">
|
||||
Users will be required to complete KYC verification for their first purchase using 'Buy with Fiat.' After that, no further KYC will be needed for future purchases on the same platform.
|
||||
</Details>
|
||||
|
||||
<Details summary="What cryptocurrencies does Payments support?">
|
||||
Payments can support any currency on our [supported chains](https://thirdweb.com/chainlist?service=pay).
|
||||
</Details>
|
||||
|
||||
<Details summary="How are cryptocurrency prices set in thirdweb Payments?">
|
||||
Prices are set depending on the liquidity provider used to route your transaction.
|
||||
</Details>
|
||||
|
||||
<Details summary="Does thirdweb Payments offer fiat payouts?">
|
||||
Fiat payouts are not currently available.
|
||||
</Details>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ export const metadata = createMetadata({
|
||||
description:
|
||||
"Monetize your app with thirdweb Payments. Sell products, transfer funds between users, launch tokens, and more.",
|
||||
image: {
|
||||
icon: "payment",
|
||||
icon: "payments",
|
||||
title: "thirdweb Payments Docs",
|
||||
},
|
||||
title: "thirdweb Payments Documentation",
|
||||
|
||||
@@ -23,8 +23,8 @@ import {
|
||||
|
||||
export const metadata = createMetadata({
|
||||
image: {
|
||||
title: "Payments",
|
||||
icon: "pay"
|
||||
title: "Get started with Payments",
|
||||
icon: "payments"
|
||||
},
|
||||
title: "Get started with Payments",
|
||||
description: "Monetize your app with thirdweb Payments. Sell products, transfer funds between users, launch tokens, and more.",
|
||||
@@ -46,7 +46,7 @@ thirdweb Payments allow developers to create advanced payment flows to monetize
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="http" className="flex items-center [&>p]:mb-0">
|
||||
<EngineIcon className="size-4 mr-1.5" />
|
||||
HTTP API
|
||||
HTTP
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
@@ -190,7 +190,7 @@ thirdweb Payments allow developers to create advanced payment flows to monetize
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="react">
|
||||
The quickest way to setup payments in your React app is with the [`BuyWidget`](/references/typescript/v5/buywidget), [`CheckoutWidget`](/references/typescript/v5/checkoutwidget), and [`TransactionWidget`](/references/typescript/v5/transactionwidget) components.
|
||||
The quickest way to setup payments in your React app is with the [`BuyWidget`](/references/typescript/v5/widgets/BuyWidget), [`CheckoutWidget`](/references/typescript/v5/widgets/CheckoutWidget), and [`TransactionWidget`](/references/typescript/v5/widgets/TransactionWidget) components.
|
||||
### Installation
|
||||
|
||||
Install the thirdweb SDK in your React project:
|
||||
|
||||
@@ -12,8 +12,8 @@ import {
|
||||
|
||||
export const metadata = createMetadata({
|
||||
image: {
|
||||
title: "Payments",
|
||||
icon: "pay",
|
||||
title: "Sell a Product",
|
||||
icon: "payments",
|
||||
},
|
||||
title: "Sell a Product",
|
||||
description: "Accept any token as payment for your products.",
|
||||
@@ -23,7 +23,7 @@ export const metadata = createMetadata({
|
||||
|
||||
Accept crypto and fiat payments for any product using the `CheckoutWidget`.
|
||||
|
||||
<Tabs defaultValue="typescript">
|
||||
<Tabs defaultValue="react">
|
||||
<TabsList>
|
||||
<TabsTrigger value="react" className="flex items-center gap-2 [&>p]:mb-0">
|
||||
<ReactIcon className="w-4 h-4 mr-2" />
|
||||
@@ -49,7 +49,7 @@ function ProductPage() {
|
||||
<div>
|
||||
<h1>Premium Course</h1>
|
||||
<p>Complete guide to web3 development</p>
|
||||
|
||||
|
||||
<CheckoutWidget
|
||||
client={client}
|
||||
chain={arbitrum}
|
||||
|
||||
@@ -22,8 +22,8 @@ import { ExternalLink } from "lucide-react";
|
||||
|
||||
export const metadata = createMetadata({
|
||||
image: {
|
||||
title: "Payments",
|
||||
icon: "pay",
|
||||
title: "Find Routes",
|
||||
icon: "payments",
|
||||
},
|
||||
title: "Find Routes",
|
||||
description: "Find available routes for bridging, swapping, and paying.",
|
||||
|
||||
@@ -21,8 +21,8 @@ import {
|
||||
|
||||
export const metadata = createMetadata({
|
||||
image: {
|
||||
title: "Payments",
|
||||
icon: "pay",
|
||||
title: "Sell Tokens",
|
||||
icon: "payments",
|
||||
},
|
||||
title: "Sell Tokens",
|
||||
description: "Learn how to sell tokens with thirdweb Payments.",
|
||||
|
||||
@@ -22,8 +22,8 @@ import { ExternalLink } from "lucide-react";
|
||||
|
||||
export const metadata = createMetadata({
|
||||
image: {
|
||||
title: "Payments",
|
||||
icon: "pay",
|
||||
title: "Send a payment",
|
||||
icon: "payments",
|
||||
},
|
||||
title: "Send a payment",
|
||||
description: "Learn how to send a payment between users with thirdweb Payments.",
|
||||
@@ -48,7 +48,7 @@ Send a payment between users using any combination of chains or tokens. thirdweb
|
||||
|
||||
```typescript
|
||||
import { Bridge } from "thirdweb";
|
||||
|
||||
|
||||
const preparedQuote = await Bridge.Buy.prepare({
|
||||
originChainId: 42161,
|
||||
originTokenAddress: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", // USDT on Arbitrum
|
||||
@@ -255,7 +255,7 @@ Send a payment between users using any combination of chains or tokens. thirdweb
|
||||
await new Promise((resolve) => setTimeout(resolve, 3000)); // Wait 3 seconds
|
||||
}
|
||||
} while (swapStatus.status === "PENDING");
|
||||
|
||||
|
||||
if (swapStatus.status === "FAILED") {
|
||||
throw new Error("Swap transaction failed");
|
||||
}
|
||||
@@ -272,10 +272,9 @@ Send a payment between users using any combination of chains or tokens. thirdweb
|
||||
|
||||
## Going further
|
||||
|
||||
- [Other auth strategies](/connect/wallet/sign-in-methods/configure)
|
||||
- [Sponsor Gas](/connect/account-abstraction/overview)
|
||||
- [Implement Sign In with Ethereum](/connect/auth)
|
||||
- [External Wallets](/connect/wallet/sign-in-methods/external-wallets) (e.g. MetaMask, WalletConnect, Coinbase Wallet, etc.)
|
||||
- [Sell a Product](/payments/products)
|
||||
- [Token Prices](/payments/tokens)
|
||||
- [Routes](/payments/routes)
|
||||
|
||||
## Explore API References
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ import { ExternalLink } from "lucide-react";
|
||||
|
||||
export const metadata = createMetadata({
|
||||
image: {
|
||||
title: "Payments",
|
||||
icon: "pay",
|
||||
title: "Get Token Prices",
|
||||
icon: "payments",
|
||||
},
|
||||
title: "Get Token Prices",
|
||||
description: "Use thirdweb Payments to get any token's current price and metadata.",
|
||||
|
||||
@@ -21,8 +21,8 @@ import {
|
||||
|
||||
export const metadata = createMetadata({
|
||||
image: {
|
||||
title: "Payments",
|
||||
icon: "pay",
|
||||
title: "Payments Webhooks",
|
||||
icon: "payments",
|
||||
},
|
||||
title: "Payments Webhooks",
|
||||
description: "Learn how to set up and handle webhooks for thirdweb Payments transactions.",
|
||||
@@ -49,17 +49,17 @@ import { Bridge } from "thirdweb";
|
||||
export async function POST(request: Request) {
|
||||
const body = await request.text();
|
||||
const headers = Object.fromEntries(request.headers.entries());
|
||||
|
||||
|
||||
try {
|
||||
const webhook = await Bridge.Webhook.parse(
|
||||
body,
|
||||
headers,
|
||||
process.env.WEBHOOK_SECRET // Your webhook secret
|
||||
);
|
||||
|
||||
|
||||
// Process the webhook
|
||||
console.log("Webhook received:", webhook);
|
||||
|
||||
|
||||
return Response.json({ success: true });
|
||||
} catch (error) {
|
||||
console.error("Webhook verification failed:", error);
|
||||
@@ -162,30 +162,30 @@ If you prefer to handle verification manually, you can verify webhooks using the
|
||||
|
||||
```typescript
|
||||
async function verifyWebhook(
|
||||
payload: string,
|
||||
headers: Record<string, string>,
|
||||
payload: string,
|
||||
headers: Record<string, string>,
|
||||
secret: string,
|
||||
tolerance = 300 // 5 minutes
|
||||
) {
|
||||
// Get the signature and timestamp from headers
|
||||
const receivedSignature = headers["x-payload-signature"] || headers["x-pay-signature"];
|
||||
const receivedTimestamp = headers["x-timestamp"] || headers["x-pay-timestamp"];
|
||||
|
||||
|
||||
if (!receivedSignature || !receivedTimestamp) {
|
||||
throw new Error("Missing required webhook headers: signature or timestamp");
|
||||
}
|
||||
|
||||
|
||||
// Verify timestamp
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
const timestamp = parseInt(receivedTimestamp, 10);
|
||||
const diff = Math.abs(now - timestamp);
|
||||
|
||||
|
||||
if (diff > tolerance) {
|
||||
throw new Error(
|
||||
`Webhook timestamp is too old. Difference: ${diff}s, tolerance: ${tolerance}s`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Generate signature using Web Crypto API
|
||||
const encoder = new TextEncoder();
|
||||
const key = await crypto.subtle.importKey(
|
||||
@@ -195,23 +195,23 @@ async function verifyWebhook(
|
||||
false,
|
||||
["sign"]
|
||||
);
|
||||
|
||||
|
||||
const signature = await crypto.subtle.sign(
|
||||
"HMAC",
|
||||
key,
|
||||
encoder.encode(`${receivedTimestamp}.${payload}`)
|
||||
);
|
||||
|
||||
|
||||
// Convert the signature to hex string
|
||||
const computedSignature = Array.from(new Uint8Array(signature))
|
||||
.map((b) => b.toString(16).padStart(2, "0"))
|
||||
.join("");
|
||||
|
||||
|
||||
// Compare signatures
|
||||
if (computedSignature !== receivedSignature) {
|
||||
throw new Error("Invalid webhook signature");
|
||||
}
|
||||
|
||||
|
||||
// Parse and return the payload
|
||||
return JSON.parse(payload);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ function Example() {
|
||||
<ArticleIconCard
|
||||
title="Supported Wallets"
|
||||
icon={TablePropertiesIcon}
|
||||
href="/connect/external-wallets"
|
||||
href="/wallets/external-wallets"
|
||||
/>
|
||||
|
||||
</Stack>
|
||||
|
||||
@@ -71,7 +71,7 @@ function Example() {
|
||||
<ArticleIconCard
|
||||
title="Supported Wallets"
|
||||
icon={TablePropertiesIcon}
|
||||
href="/connect/external-wallets"
|
||||
href="/wallets/external-wallets"
|
||||
/>
|
||||
|
||||
</Stack>
|
||||
|
||||
@@ -14,7 +14,7 @@ export const metadata = createMetadata({
|
||||
|
||||
# Connection Hooks
|
||||
|
||||
You can build a completely custom UI for connecting the wallet using the [`useConnect`](/references/typescript/v5/useConnect) hook to connect any of [supported wallets](/connect/external-wallets).
|
||||
You can build a completely custom UI for connecting the wallet using the [`useConnect`](/references/typescript/v5/useConnect) hook to connect any of [supported wallets](/wallets/external-wallets).
|
||||
|
||||
```tsx
|
||||
import { createThirdwebClient } from "thirdweb";
|
||||
|
||||
@@ -106,8 +106,8 @@ The SDK supports 500+ wallets out of the box, all you need to pass is their id.
|
||||
<ArticleIconCard
|
||||
title="Supported Wallets"
|
||||
icon={ComponentIcon}
|
||||
href="/connect/external-wallets"
|
||||
description="See all 500+ wallets supported by the Connect SDK"
|
||||
href="/wallets/external-wallets"
|
||||
description="See all 500+ wallets supported by the TypeScript SDK"
|
||||
/>
|
||||
|
||||
</Stack>
|
||||
|
||||
@@ -91,14 +91,14 @@ await sendTransaction({ transaction, account });
|
||||
|
||||
## Full Reference
|
||||
|
||||
View everything you can do in the Connect SDK once you have connected your wallet:
|
||||
View everything you can do in the TypeScript SDK once you have connected your wallet:
|
||||
|
||||
<Grid className="lg:grid-cols-2">
|
||||
|
||||
<ArticleIconCard
|
||||
href={"/typescript/v5"}
|
||||
image={WalletIcon}
|
||||
title="Connect SDK reference"
|
||||
title="TypeScript SDK reference"
|
||||
/>
|
||||
|
||||
</Grid>
|
||||
|
||||
@@ -84,7 +84,7 @@ import { ThirdwebProvider } from "thirdweb/react"; // v5
|
||||
Similar to v4's `ConnectWallet` component, the latest version has the [`ConnectButton`](/connect/sign-in/ConnectButton) component which has the same functionality.
|
||||
|
||||
However, unlike with v4 where the number of supported wallets is limited (about 20), and adding more wallets mean your app becomes heavier,
|
||||
the SDK v5 supports [over 300 wallets](/connect/external-wallets) with virtually no impact to your application.
|
||||
the SDK v5 supports [over 300 wallets](/wallets/external-wallets) with virtually no impact to your application.
|
||||
|
||||
Here's how you use the new `ConnectButton`:
|
||||
|
||||
@@ -99,7 +99,7 @@ const client = createThirdwebClient({
|
||||
<ConnectButton client={client} />
|
||||
```
|
||||
|
||||
To learn more about the new `ConnectButton`, head over to the [Playground](https://playground.thirdweb.com/connect/sign-in/button).
|
||||
To learn more about the new `ConnectButton`, head over to the [Playground](/connect/sign-in/button).
|
||||
|
||||
Notice how you are passing the thirdweb client to the component itself and not to the `ThirdwebProvider` like in v4?
|
||||
By not putting every config inside the context wrapper, we were able to make the SDK v5 much more lightweight since you only load what you need!
|
||||
|
||||
@@ -27,7 +27,7 @@ Learn how to migrate to thirdweb's ConnectButton component from [RainbowKit](htt
|
||||
|
||||
<Steps>
|
||||
<Step title="Installation">
|
||||
Install the connect SDK in your application
|
||||
Install the TypeScript SDK in your application
|
||||
<InstallTabs
|
||||
npm="npm i thirdweb"
|
||||
yarn="yarn add thirdweb"
|
||||
|
||||
@@ -51,7 +51,7 @@ export const sidebar: SideBar = {
|
||||
name: "Ecosystems Wallets",
|
||||
},
|
||||
{
|
||||
href: "/connect/external-wallets",
|
||||
href: "/wallets/external-wallets",
|
||||
name: "External Wallets",
|
||||
},
|
||||
{
|
||||
|
||||
@@ -258,12 +258,10 @@ export function getSidebarLinkGroups(doc: TransformedDoc, path: string) {
|
||||
const bridgeGroups = bridge.reduce(
|
||||
(acc, d) => {
|
||||
const [, moduleName] = getCustomTag(d) || [];
|
||||
if (moduleName) {
|
||||
if (!acc[moduleName]) {
|
||||
acc[moduleName] = [];
|
||||
}
|
||||
acc[moduleName]?.push(d);
|
||||
if (!acc[moduleName ?? "common"]) {
|
||||
acc[moduleName ?? "common"] = [];
|
||||
}
|
||||
acc[moduleName ?? "common"]?.push(d);
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, SomeDoc[]>,
|
||||
|
||||
@@ -5,7 +5,7 @@ import { getTDocLayout } from "@/app/references/components/TDoc/PageLayout";
|
||||
export default getTDocLayout({
|
||||
getDoc: fetchTypeScriptDoc,
|
||||
packageSlug: "typescript",
|
||||
sdkTitle: "Connect SDK",
|
||||
sdkTitle: "TypeScript SDK",
|
||||
});
|
||||
|
||||
export const metadata = createMetadata({
|
||||
|
||||
|
Before Width: | Height: | Size: 867 KiB After Width: | Height: | Size: 867 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user